SWIFT OS X - multiple statements inside a closure statement, a debugging tool? - arrays

I am using the following code to filter a large array:
var arrayOfSelectedRowDetails = self.projectRowDetails.filter(
{ $0.projectNumber == self.projectNumberArray[selectedRow] }
)
Normally the code runs fine and I have no issues. But in one scenario (after I have deleted some management objects from the persistent store) and then rerun the code I am getting a EXC_BAD_ACCESS (code = 1, address=0x0) error at runtime.
I have set a break and stepped through the runtime of this statement. It is a large array built from a core data entity (using a fetch statement) - and therefore takes a long time. When I step through the code over the first dozen or so indexes the code runs ok - when i remove the break and let it run it then presents the error.
Is it possible to println() from within the closure statement to assist with debugging? I have tried a number of different syntaxes and cannot get it to work.
Alternatively, is it possible to set an error capture statement within the closure so that the code ceases through a break or an abort() statement?
Fundamentally i am trying to identify the index of the array at the point that the error occurs so that I can get sufficient information to debug the delete function (which is where I think the error is). I do not seem to be able to ascertain the index from the info available to me when the error occurs.
This is the first time I have tried programming in Swift and making use of closures so I am learning as I go. Apologies if I am asking fundamental questions. I have not been able to find a similar question elsewhere here with an answer that works.

You can set an exception breakpoint in Xcode (for an example see here).
Also, I suggest that you move the access to self.projectNumberArray out of the closure:
let pn = self.projectNumberArray[selectedRow]
var arrayOfSelectedRowDetails = self.projectRowDetails.filter(
{ $0.projectNumber == pn }
)
The change might not solve the issue, but it will at least help the debugging.
Lastly, if you want to print the index, the following approach will probably work:
let pn = self.projectNumberArray[selectedRow]
var index = 0
var arrayOfSelectedRowDetails = self.projectRowDetails.filter(
{ println(index++); return $0.projectNumber == pn }
)

Related

Detecting collision between an object inside a movie clip that is in an array vs another array of objects

Simply,
I have randomly placed and moving movie clips that will call victims And I Have another set of random Moving movie clips that have an attack animation I will call them assailants.
Victims wander randomly among Assailants an at random times the Assailants will shoot out a lightning bolt movie clip to attack the victims. It is at this point I am attempting to check for a collision between the victims and the assailants lightning Bolts.
Both types are in separate array's and I have before checked an array vs an array without a problem I have also checked static object vs an array objects internal MC without an issue. However I am Stuck when checking array vs array objects internal MC.
Code:
for(var j:int=0;j<NormalBubbleArray.length;j++){
for(var k:int=0;k<LightningStormArray.length;k++){
if(NormalBubbleArray[j].hitTestObject(LightningStormArray[k]).upbolt){
trace("hit")
NormalBubbleArray.removeAt([j]);
LightningStormArray.removeAt([k]);
}
}
}
I have also Tried
if(NormalBubbleArray[j].hitTestObject(LightningStormArray[k]).upbolt)
and 10 other ways to try and write it. Still no luck not sure if its my loop or collision detection at this point. It gives no errors when running so I assume my Syntax is Ok.
Thanks In Advance.
Update: I was tinkering with it and realized I had it wrapped in a try catch so I was not seeing the error. now my issue is this.
for(var j = 0; j<NormalBubbleArray.length;j++){
for(var k = 0; k<LightningStormArray.length;k++){
if((LightningStormArray[k]).upbolt hitTestPoint(NormalBubbleArray [j]), true){
trace("hit")
(NormalBubbleArray [j]).removeEventListener(MouseEvent.MOUSE_MOVE, ChildMouse);
NormalBubbleArray.removeAt([j]);
LightningStormArray.removeAt([k]);
}
}
}
Still Compiles but when it comes time to detect I get The following error in the output.
TypeError: Error #1006: value is not a function.
at BubblesReloaded_fla::MainTimeline/CollisionControl()
Help is appreciated.. I am still tinkering with it.
Got it !
Tricky Devil.
The debuger kept pointing to the hittest line and it had nothing to do with the actual line it hilighted but what was inside the if statment that caused the issue.
var Lstormpoints:int = 0;
for(var j = 0; j<NormalBubbleArray.length;j++){
for(var k = 0; k<LightningStormArray.length;k++){
if(LightningStormArray[k].upbolt.hitTestPoint(NormalBubbleArray [j]), true){
trace("bubble is hit")
NormalBubbleArray [j].removeEventListener(MouseEvent.MOUSE_MOVE, ChildMouse);
NormalBubbleArray [j].gotoAndPlay(10)/// was (NormalBubbleArray [j]).gotoAndPlay(10) // was causing an error
NormalBubbleArray.removeAt([j]);
LightningStormArray.removeAt([k]);
}
}
}
What threw me off was that the debugger kept pointing to the if statement as the error. What I did not catch is it was trying to tell me that it was an error inside the if statement. I figured it out after some heavy tracing I Noticed that it was detecting collision but the Bubble was not acting as if it got hit giving me the illusion that it was not detecting hit. the gotoAndPlay line animates the death and sadly that was the line with the issue.. just happy I got it going.

AS3: hitTestObject turning up null for no apparent reason

I'm currently coding a game, and in one part of the code, it's checking to see if the player is close enough to a monster in mArray for its health bar to appear. I use hitTestObject for this with var i incrementing to go through the list. However, I will randomly get this error message:
TypeError: Error #2007: Parameter hitTestObject must be non-null.
After seeing this for the first time, I put the test all under the conditional if (mArray.length > 0) to make sure the Array() was filled before even attempting the test... but it still occurs at random times. I even used trace(i) to see if it happened on a certain part of the list, but it's completely random each debug session! I know the player portion can't be null since it is on the screen at all times during the hitTest, so I'm at a loss for words right now.
The portion of code in question (nothing else is related to this except for the use of mArray[i] in different places):
for (var i:int = 0; i < mArray.length; i++) {
if (mArray.length > 0) {
trace(i); //my attempt to see if it occurred at a specific incrementation of i
if (player.hitTestObject(mArray[i])) {
mArray[i].healthBar.visible = true;
} else {
mArray[i].healthBar.visible = false;
}
}
}
Again, it works perfectly for everything all of the time except for random cases it gives me the TypeError. Is this just a hiccup in my code, is there some obvious problem that I'm overlooking, or does the code just like to throwback to 2007?
EDIT: The debug session ALWAYS points to the line with if (player.hitTestObject(mArray[i])).
It looks like for some i the mArray[i] has a null value. Either make sure this won't happen when populating the array or just add extra check in hitTestObject line like this:
if (mArray[i] && player.hitTestObject(mArray[i])) { ... }
I don't know your game's architecture but maybe it would be more convenient to move the hitTestObject test into monster class instead of checking it externally. Typical approach is to have each entity to have some kind of "update" method that is executed once in every game loop.

Using a loop to assign labels won't work in Actionscript 3. TypeError: Error #1010

I've used this website for many things and found a lot of useful information that has helped me create a randomized quiz mostly. I'm trying to make the code as efficient as possible and that has led me to this error.
I have created an array which uses the .push function to store existing buttons on the stage into the array for future use. The code shown below sets the label of each button correctly.
_buttons[0].label = xmlData.difficulty1.questions[num2].op1.text();
_buttons[1].label = xmlData.difficulty1.questions[num2].op2.text();
_buttons[2].label = xmlData.difficulty1.questions[num2].op3.text();
_buttons[3].label = xmlData.difficulty1.questions[num2].op4.text();
So naturally I wanted to make this a little more efficient and put these in a loop. Based on the logic this SHOULD work but doesn't.
for (var i:Number = 0; i < 4; i++)
{
_buttons[i].label = xmlData.difficulty1.questions[num2].op[i+1].text();
}
This code should simply increment the array counter of _buttons and set the label for each. I mean it's simply the first set of code in a for loop right? However when I run it I get the following error: TypeError: Error #1010: A term is undefined and has no properties.
Now I know for sure that the first set of code works as I have tested it repeatedly but as soon as I decide to put it into that for loop, it fails. Could anyone explain why? Perhaps it's a limitation of the language itself? Maybe I'm missing a command?
Try :
for (var i:Number = 0; i < 4; i++)
{
_buttons[i].label = xmlData.difficulty1.questions[num2]['op'+(i+1)].text();
}
.op[i+1] tries to access a property called 1 under a field called op instead of op1

setting object properties value for object array in matlab

I have created an array of objects and I would like assign a property value in a vector operation without using a for loop. Unfortunately I get an error.
A simplified example of the problem.
classdef clsMyClass < handle
properties
dblMyProperty1
end
methods
function obj = clsMyClass()
end
end
end
And when running
vecMyArray = clsMyClass.empty(100,0);
vecMyArray(100) = clsMyClass;
vecMyArray.dblMyProperty1 = 1:100;
We get the following error:
??? Incorrect number of right hand side elements in dot name
assignment. Missing [] around left hand side is a likely cause.
Any help would be appreciated.
I see what you're trying to do now. Use disperse from the MATLAB File Exchange:
>> [vecMyArray.dblMyProperty1] = disperse(1:100);
>> vecMyArray(1).dblMyProperty1
ans =
1
>> vecMyArray(10).dblMyProperty1
ans =
10
You can use the deal function for exactly this purpose:
[vecMyArray.dblMyProperty1] = deal(1:100);
See: http://www.mathworks.com/company/newsletters/articles/whats-the-big-deal.html
Edit: No you can't, actually; that'll set them to all be the vector 1:100.
I think you'll find your answer here in "Struct array errors." Even though this is a class, similar rules apply.
Unfortunately missing [] is not the cause, since adding them causes more errors. The cause is that you cannot assign the same value to all fields of the same name at once, you must do it one at a time, as in the following code:
So you'll need:
for ii=1:100
vecMyArray(ii).dblMyProperty1 = ii;
end
I know it's not satisfying, but I think it at least helps us to definitively understand this error.

Ada and SPARK identifier `State` is either undeclared or not visible at this point

I am doing an automatic train protection on Ada with SPARK approach. This is my spec in SPARK:
package Sensors
--# own State,Pointer,State1,State2;
--# initializes State,Pointer,State1,State2;
is
type Sensor_Type is (Proceed, Caution, Danger, Undef);
subtype Sensor_Index_Type is Integer range 1..3;
procedure Write_Sensors(Value_1, Value_2, Value_3: in Sensor_Type);
--# global in out State,Pointer;
--# derives State from State,Value_1, Value_2, Value_3,Pointer &
--# Pointer from Pointer;
function Read_Sensor(Sensor_Index: in Sensor_Index_Type) return Sensor_Type;
function Read_Sensor_Majority return Sensor_Type;
end Sensors;
and this is my Ada:
package body Sensors is
type Vector is array(Sensor_Index_Type) of Sensor_Type;
State: Vector;
Pointer:Integer;
State1:Sensor_Type;
State2:Sensor_Type;
procedure Write_Sensors(Value_1, Value_2, Value_3: in Sensor_Type) is
begin
State(Pointer):=Value_1;
Pointer:= Pointer + 1;
State(Pointer):=Value_2;
Pointer:= Pointer + 1;
State(Pointer):=Value_3;
end Write_Sensors;
function Read_Sensor (Sensor_Index: in Sensor_Index_Type) return Sensor_Type
is
State1:Sensor_Type;
begin
State1:=Proceed;
if Sensor_Index=1 then
State1:=Proceed;
elsif Sensor_Index=2 then
State1:=Caution;
elsif Sensor_Index=3 then
State1:=Danger;
end if;
return State1;
end Read_Sensor;
function Read_Sensor_Majority return Sensor_Type is
State2:Sensor_Type;
begin
State2 := state(1);
return State2;
end Read_Sensor_Majority;
begin -- initialization
State:=Vector'(Sensor_Index_Type =>Proceed);
pointer:= 0;
State1:=Proceed;
State2:=Proceed;
end Sensors;
I want to know why in the function Read_Sensor_Majority I can't use the State(1) or any of the State() array values. If there is a way to use them, should I put anything in the specs of SPARK to make it happen?
The errors it's showing are:
1)Expression contains referenced to variable state which has an undefined value flow error 20
2)the variable state is nether imported nor defined flow error 32
3)the undefined initial value of state maybe used in the derivation of the function value flow error 602
You need to change the spec to read
function Read_Sensor_Majority return Sensor_Type;
--# global in State;
As I said in the comments above, I was puzzled by
State := Vector'(Sensor_Index_Type => Proceed);
but the compiler accepts it so it must be OK. And a little test shows that it has the same effect as
State := Vector'(others => Proceed);
Also pleased to report that the SPARK GPL 2011 toolset is now available for Mac OS X!
Heh. Well, those are definitely SPARK errors, rather than "garden variety" compiler errors.
It would be nice to see an actual cut-and-paste version of the errors (along with an indication of which lines they are referring to) rather than just an imperfect transcription. However, I do realise that isn't always possible for security/connectivity reasons.
It looks like all three are complaining about the flow of data through your system. Without knowing which lines they refer to, the best I can suggest is to try to manually trace your flow of data through your system to try to see what their problem is.
If I had to take a wild guess with the info I have here, I'd say it perhaps has a problem with your reading of a value from State(1) in the routine Read_Sensor_Majority, because it has no way of knowing that you've previously placed a value into that array location.
The code you have in the package's begin...end body area should take care of that, except it appears to have a compile error itself, as Simon pointed out in the comments. Perhaps if you fix that problem, SPARK will understand what is going on and quit complaining about your control flows.
If SPARK likes to spit out "I'm confused" errors on code that doesn't even get past the Ada compiler, it might be wise to make sure the Ada compiler likes the pure Ada part of your code before asking SPARK to look it over.

Resources