NSTimer 再按 "Start" 然后不能 "Stop"

NSTimer Press "Start" Again then Cannot "Stop"

一个奇怪的情况:

如果我一次又一次地启动我的计时器而不先停止它,它会越来越快。我猜是因为它现在启动了多个计时器?

可是,当我终于想停下来的时候,却停不下来……一直走下去。

(也许出于设计考虑,我应该禁止用户再次按下开始,但我想知道这背后到底是什么,为什么计时器不能停止。)

- (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

当您多次点击 'start' 时,您正在创建多个计时器。因此,您将触发多个计时器并执行您的计时器回调。在此计时器回调中,您递增计数器。由于现在有很多计时器,它们都在增加你的计数器,因此解释了你快速增加计数器的原因。

您可以允许用户点击“开始”两次,只要您可以定义在计时器已经开始时点击“开始”时会发生什么。但是在创建新计时器之前,您肯定需要 invalidate 旧计时器。

- (IBAction)Start:(id)sender {
    ...
    // Stop previous timer before creating a new timer.
    if (timer != nil) {
        [timer invalidate]
    }
    ...
}

简单的解决方法是在start方法的开头调用stop

请注意,在 stop 中您还应该设置 timer = nil;

假设有一个 属性 timer

@property NSTimer *timer;

最可靠的分别只启动和停止定时器一次的方法是创建两个方法。

- (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;
    }
}

这两种方法都执行检查,因此计时器在 运行 时无法重新启动,反之亦然。

现在只需调用 start/stop IBActions 中的方法(名称应以小写字母开头)。

- (IBAction)Start:(id)sender {
    countInt = 0;
    self.Time.text = [NSString stringWithFormat:@"%i", countInt];
    [self startTimer];
}

- (IBAction)Stop:(id)sender {
   [self stopTimer];
}

当定时器已经运行时,按下Start的好处是无效的。