PDA

View Full Version : Really weird error




xcodeNewbie
Aug 14, 2011, 03:52 PM
I've been having trouble getting the following bit of code to work right:
for (Planet *aPlanet in planetArray) {
[aPlanet.makeShipTimer invalidate];
}
It always crashes when it runs this part. So I tried it like this:
for (Planet *aPlanet in planetArray) {
if ([aPlanet.makeShipTimer isValid]) [aPlanet.makeShipTimer invalidate];
}
And it still crashes. So I added an NSLog:
for (Planet *aPlanet in planetArray) {
if ([aPlanet.makeShipTimer isValid]) NSLog(@"Valid!");
}
And the NSLog shows up, which means that the timer is valid. Any idea what's going on?



jiminaus
Aug 14, 2011, 05:30 PM
My first thought is that the Planet objects have been deallocated. Run your program under Instruments using the zombies template.

isValid returning true doesn't contradict my theory. The behaviour of sending a message to a deallocated object is undefined.

isValid doesn't check if the timer is still allocated, it only checks if the timer is still capable of firing. This could be simply returning a BOOL ivar. That could be why your program doesn't crash at this point.

xcodeNewbie
Aug 14, 2011, 06:46 PM
Thanks for your reply, but I already ran an NSLog test that confirmed the planets still exist.

jiminaus
Aug 14, 2011, 09:21 PM
but I already ran an NSLog test that confirmed the planets still exist.

How did you do that? That NSLog code you posted above does not check whether the object exists.

RonC
Aug 14, 2011, 09:55 PM
I've been having trouble getting the following bit of code to work right:
for (Planet *aPlanet in planetArray) {
[aPlanet.makeShipTimer invalidate];
}
It always crashes when it runs this part. So I tried it like this:


A couple of thoughts:
When you say it crashes, what do you mean? Do you get a stack backtrace in the console output? Care to share?

Have you run it under the debugger, with a breakpoint on both the line within the for loop? You can re-write that code slightly to make debugging a little easier, something like:
for (Planet *aPlanet in planetArray) {
NSTimer *makeShipTimer = [aPlanet.makeShipTimer]; // guessing on type
[makeShipTimer invalidate];
}

You can set the breakpoint on the invalidate statement and see the result of the makeShipTimer call.

KoolStar
Aug 15, 2011, 04:47 AM
It also depends on what properties that the op declared in the header for the nstimer as well as if he is setting to nil anywhere after he invalidates the timer.