Like this:
- (void)timerFired:(id)sender {
_timer = nil;
// do thing here
}
- (IBAction)handleTap:(id)sender {
[_timer invalidate];
_timer = [NSTimer scheduledTimerWithTimeInterval:3.0
target:self
selector:@selector(timerFired:)
userInfo:nil
repeats:NO];
}
- (void)dealloc {
[_timer invalidate];
}
There's a few key things you need to do here:
- In the code that handles the firing of the timer, set the instance variable to nil.
- Invalidate the old timer before creating the new one.
- Don't worry about checking the timer's validity before invalidating it. If you follow this technique, the timer will either be valid or nil. It's perfectly safe to call
invalidate
on nil. - You don't have to nil
_timer
between invalidating it and reassigning it; this code is all on the main thread. If you were just cancelling the timer, though, you would.- The reason for this is that this timer has been scheduled on the runloop. That guarantees it won't fire until the next iteration of the runloop. The runloop will not iterate until you return.
- In
dealloc
, you should invalidate the timer. (It might be more appropriate for you to do this inviewDidDisppear:
; if you do, make sure you nil it after.)