简体   繁体   English

Objective-C计时器不会失效

[英]Objective-c timer wont invalidate

Here is my situation: I am making a countdown app which works fine but does not appear to stop when I call [stopWatchTimer invalidate]; 这是我的情况:我正在制作一个倒计时应用程序,该应用程序运行正常,但在我调用[stopWatchTimer invalidate];时似乎没有停止[stopWatchTimer invalidate]; , and I have no idea why. ,我也不知道为什么。 Here is my code: 这是我的代码:

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

Please let me know what the problem is... I cannot find a problem with my code anywhere! 请让我知道问题出在哪里...我的代码在任何地方都找不到问题!

In your btnStartPressed: method, you have nothing preventing a second NSTimer from being allocated and assigned to stopWatchTimer . btnStartPressed:方法中,您什么都无法阻止将第二个NSTimer分配并分配给stopWatchTimer If you press the button twice, you'll end up with two timers, but only one will ever be invalidated. 如果您按两次按钮,最终将有两个计时器,但是只有一个计时器将被无效。

Add something like: 添加类似:

 if (stopWatchTimer) return;

To the beginning of btnStartPressed: . btnStartPressed:的开头btnStartPressed: If that doesn't fix the problem, then there isn't enough context to know for sure what is going on beyond conjecturing that timeLeft is zero? 如果那不能解决问题,那么没有足够的上下文可以肯定,除了猜测timeLeft为零之外,还发生了什么?


What Nate said, but here is another explanation. 内特所说的,但这是另一种解释。

Imagine if you do this (where stopWatchTimer is a global or instance variable, doesn't matter): 试想一下,如果您这样做(stopWatchTimer是全局变量或实例变量,则没有关系):

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

Now, do this: 现在,执行以下操作:

 stopWatchTimer = nil;
 [stopWatchTimer invalidate];

The timer won't invalidate, but it'll still fire. 计时器不会失效,但仍会触发。 stopWatchTimer is a reference to the object. stopWatchTimer是对该对象的引用 It isn't the object itself. 它不是对象本身。 Thus, when you assign a second timer to stopWatchTimer , you are overwriting the reference to the first timer, but that timer is still going to fire! 因此,当您将第二个计时器分配给stopWatchTimer ,您将覆盖对第一个计时器的引用,但是该计时器仍将启动!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM