Reputation: 463
A strange situation:
If I started my Timer again and again without stopping it first, it will count increasingly fast. I guess it is because it starts multiple timers now?
However, when I finally want to stop it, it cannot be stopped...keep going forever.
(Maybe for design consideration, I should disable users from pressing start again, but I'm wondering what is really behind this and why the timer can't be stopped.)
- (IBAction)Start:(id)sender {
countInt = 0;
self.Time.text = [NSString stringWithFormat:@"%i", countInt];
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(countTimer) userInfo:nil repeats:YES];
}
- (IBAction)Stop:(id)sender {
[timer invalidate];
}
- (void) countTimer {
countInt += 1;
self.Time.text = [NSString stringWithFormat:@"%i", countInt];
}
@end
Upvotes: 0
Views: 99
Reputation: 7287
When you hit 'start' multiple times you are creating multiple timers. So you are getting multiple timers firing and executing your timer callback. In this timer callback you increment counters. Since there are many timers now, they are all incrementing your counter, hence explaining your rapid increase in the counter.
You can allow the user to tap Start twice, as long you can define what happens when you hit Start while the timer is already going. But you definitely need to invalidate
the old timer before creating a new one.
- (IBAction)Start:(id)sender {
...
// Stop previous timer before creating a new timer.
if (timer != nil) {
[timer invalidate]
}
...
}
Upvotes: 0
Reputation: 285059
Assuming there is a property timer
@property NSTimer *timer;
the most reliable way to start and stop the timer only once respectively is to create two methods.
- (void)startTimer
{
if (self.timer == nil) {
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(countTimer)
userInfo:nil
repeats:YES];
}
}
- (void)stopTimer
{
if (self.timer != nil) {
[self.timer invalidate];
self.timer = nil;
}
}
Both methods perform a check, so the timer can't be restarted while it's running and vice versa.
Now just call the methods in the start/stop
IBActions (the names should start with a lowercase letter).
- (IBAction)Start:(id)sender {
countInt = 0;
self.Time.text = [NSString stringWithFormat:@"%i", countInt];
[self startTimer];
}
- (IBAction)Stop:(id)sender {
[self stopTimer];
}
The benefit is pressing Start
has no effect when the timer is already running.
Upvotes: 2
Reputation: 119021
The simple solution is to call stop
at the beginning of the start
method.
Note that in stop
you should also set timer = nil;
Upvotes: 3