Ok, here is the error I am getting:
-[CFRunLoopTimer invalidate]: message sent to deallocated instance 0x109b05a0 (gdb)
Here is the code causing the crash:
if (waitingOpponentTimer) {
[waitingOpponentTimer invalidate]; //<-- Crash/error occurs here
waitingOpponentTimer = nil;
}
And elsewhere:
NSTimer* waitingOpponentTimer;
And also:
waitingOpponentTimer = [NSTimer scheduledTimerWithTimeInterval:10.0f target:self selector:@selector(waitingOpponentTimeOut)userInfo:nil repeats:NO];
There is NO other occurence of waitingOpponentTimer anywhere, only the ones I have shown above. waitingOpponentTimeOut action just sets a few variables and does nothing to timers or to waitingOpponentTimer.
I have tried all the following IF statements to prevent the invalidate statement from being reached:
if (waitingOpponentTimer) {
if ([waitingOpponentTimer retainCount] > 0) {
if (waitingOpponentTimer.isValid) {
if (waitingOpponentTimer != nil) {
But in all cases, it still gets thru the IF statement and then causes the crash with the invalidate statement.
So my question is, why/how is invalidate causing an error when the object isValid and is not nil and it's retainCount is greater than zero?
Is there another way to check this to prevent invalidate from being reached?
I am a complete noob to iphone programming and have spent several hours googling to try and figure this out but cannot figure out what I am doing wrong. Any help and suggestions appreciated!
EDIT: Just to clarify, I am using this to manually stop the timer before it runs. I understand that if it runs out, it invalidates itself, which is why I am using the IF statement to check if it has already been invalidated (but it is not working). So I think the timer has already invalidated itself when this crash happens, but how do I check if it is already invalidated?
EDIT: Ok I marked the correct answer below. I do not know if there is actually a reason why the code gets by the IF statements when the timer was not retained and has already invalidated itself, but the answer is to always use RETAIN if you are going to use the timer in an IF statement.
Here is related info: Is there any reason to retain a scheduled NSTimer if you don't need to invalidate it?
Most likely, you don't need to invalidate the timer. Since the timer is not repeating, it will invalidate itself once the allocated time has reached the end. This could be why the app is crashing, as well. If the timer has reached the end of its run, it sends itself the invalidate message, so when you call it later, it doesn't know what to do since it has already been invalidated. So my suggestion would be to just ignore the invalidating since it will handle itself (so long as it's non-repeating)
Do you use ARC?
try calling isValid before starting the timer
that way you cant accidentally create 2 instances of it
think about this
there is still a timer floating around, and if it fires when your not expecting it can cause problems. so ya i would test for isValid before calling it