This question has been asked to death on stack overflow, and I’ve seen a plethora of answers but somehow I’m still having trouble.
Anyway, I allocate an NSTimer as so in my view did load:
NSTimer *oneSecondTicker = [[NSTimer alloc] init];
oneSecondTicker = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateLabelsWithOneSecondTicker) userInfo:nil repeats:YES];
self.dateForTimeLabel = [NSDate date];
the method that is the selector is:
-(void) updateLabelsWithOneSecondTicker {
if(self.dateForTimeLabel != nil)
{
self.lblTime.text = [NSString stringWithFormat:@"%f", fabs([self.dateForTimeLabel timeIntervalSinceNow])];
}
}
This method basically updates a label each second, giving me a timer/stopwatch sort of thing.
I also have a start/pause button, which when pressed to pause does:
[oneSecondTicker invalidate];
oneSecondTicker = nil;
if the button is pressed to start again, the method is:
NSTimer *oneSecondTicker = [[NSTimer alloc] init];
oneSecondTicker = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateLabelsWithOneSecondTicker) userInfo:nil repeats:YES];
self.dateForTimeLabel = [NSDate date];
I do not call retain to the timer, and it has no property and it does not get synthesized. It is however getting declared in the interface.
To get to the issue, what happens with each pause/start button press is that the timers do not get invalidated, and the time label becomes updated quicker and quicker, leading me to believe that multiple timers exist for some reason. (Obviously the functionality for a real timer is not to be found in these methods yet, and this is just a test to get my NSTimer to work).
How can this be?
You wrote this:
That line creates a local variable. It does not set the property that you declared in your interface. That line also creates a timer, which you immediately destroy in the next line when you reassign
oneSecondTickerto point at the timer you create withscheduledTimerWithTimeInterval:. This is a beginner mistake that indicates that you need to learn how pointers work.Anyway, you’re creating your timer using
scheduledTimerWithTimeInterval:.... That means the timer is automatically scheduling itself in the run loop. When a timer is scheduled in a run loop, the run loop retains the timer. That’s why (assuming you’re using ARC) the timer lives on even though you’re releasing your reference to it.You need to store the timer in your instance variable. I assume you are using Xcode 4.4 or later, so the property is being automatically synthesized. If you declared the property like
@property (nonatomic, strong) NSTimer *oneSecondTicker, then you can create the timer like this:and when you want to invaldate it, you can say this: