Objective-c计时器不会失效

时间:2012-12-31 00:18:02

标签: objective-c timer nstimer invalidation

以下是我的情况:我正在制作倒计时应用程序,该工作正常,但在我致电[stopWatchTimer invalidate];时似乎没有停止,我不明白为什么。这是我的代码:

- (IBAction)btnStartPressed:(id)sender {
//Start countdown with the time on the Date Picker.

    timeLeft = [pkrTime countDownDuration];

    [self currentCount];

    lblTimer.text = time; //sets the label to the time set above

    pkrTime.hidden = YES;
    btnStart.hidden = YES;
    btnStop.hidden = NO;

    //Fire this timer every second.
    stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/1.0
                                                  target:self
                                                selector:@selector(reduceTimeLeft:)
                                                userInfo:nil
                                                 repeats:YES];
}
- (void)reduceTimeLeft:(NSTimer *)timer {
    //Countown timeleft by a second each time this function is called
    timeLeft--;
    // Get the system calendar
    NSCalendar *sysCalendar = [NSCalendar currentCalendar];

    // Create the NSDates
    NSDate *date1 = [[NSDate alloc] init];
    NSDate *date2 = [[NSDate alloc] initWithTimeInterval:timeLeft sinceDate:date1];

    // Get conversion to months, days, hours, minutes
    unsigned int unitFlags = NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;

    NSDateComponents *conversionInfo = [sysCalendar components:unitFlags fromDate:date1  toDate:date2  options:0];

    int sec = [conversionInfo second];
    int min = [conversionInfo minute];
    int hour = [conversionInfo hour];

    NSString *seconds = [NSString stringWithFormat:@"%d",sec];
    NSString *minutes = [NSString stringWithFormat:@"%d",min];

    if (sec <= 9)
        seconds = [NSString stringWithFormat:@"0%d", sec];
    if (min <= 9)
        minutes = [NSString stringWithFormat:@"0%d", min];

    if ([conversionInfo hour] == 0)
        time = [NSString stringWithFormat:@"%@:%@", minutes, seconds];
    else
        time = [NSString stringWithFormat:@"%d:%@:%@", hour, minutes, seconds];

    lblTimer.text = time; //sets the label to the time set above

    NSLog(@"%d", timeLeft);

    if (timeLeft == 0) {
        [self timerDone];
        [stopWatchTimer invalidate];
        stopWatchTimer = nil;
    }
}

-(void)timerDone {

    pkrTime.hidden = NO;
    btnStart.hidden = NO;
    btnStop.hidden = YES;

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Timer Done" message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:@"Ok", nil];
    [alert show];

    [self playAlert];
}

请让我知道问题是什么......我在任何地方找不到代码的问题!

1 个答案:

答案 0 :(得分:1)

btnStartPressed:方法中,您无法阻止第二个NSTimer被分配并分配给stopWatchTimer。如果按两次按钮,最终会有两个定时器,但只有一个定时器会失效。

添加如下内容:

 if (stopWatchTimer) return;

btnStartPressed:的开头。如果这不能解决问题,那么没有足够的上下文可以确定除了推测timeLeft为零之外还有什么事情发生?


Nate说,但这是另一种解释。

想象一下,如果你这样做(其中stopWatchTimer是全局或实例变量,无所谓):

 stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:....];

现在,这样做:

 stopWatchTimer = nil;
 [stopWatchTimer invalidate];

计时器不会失效,但它仍会触发。 stopWatchTimer是对象的引用。它不是对象本身。因此,当您将第二个计时器分配给stopWatchTimer时,您将覆盖对第一个计时器的引用,但该计时器仍将触发!