0

我的计时器从viewDidLoad. 计时器第一次调用选择器时,预期的结果很好。但是逐渐地,当进行调用时,选择器会以某种方式多次调用该函数。我记录了一个NSLog显示输出数量正在增加的结果。我有下面的代码。希望它使情况清楚。

-(void)viewDidLoad
{
    remainingTicks = 10;
    [self updateLabel];
    myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
                       target:self
                       selector:@selector(handleTimerTick)
                       userInfo:nil
                       repeats:YES];
}

-(void)handleTimerTick
{
    remainingTicks--;
    [self updateLabel];
    if (remainingTicks <= 0) {
        [myTimer invalidate];
        myTimer = nil;
        UIButton *but = [[UIButton alloc] init];
        if (answerAt == 0) {
            [buttonA setBackgroundColor:[UIColor greenColor]];
        }
        else if (answerAt == 1) {
            [buttonB setBackgroundColor:[UIColor greenColor]];
        }
        else if (answerAt == 2) {
            [buttonC setBackgroundColor:[UIColor greenColor]];
        }
        else {
            [buttonD setBackgroundColor:[UIColor greenColor]];
        }

        [self performSelector:@selector(next:) withObject:but afterDelay:1.5 ];       
    }
}

-(void)updateLabel
{
    timerLabel.text = [[NSNumber numberWithUnsignedInt: remainingTicks] stringValue];
}
4

2 回答 2

0

ViewDidLoad可以在 a 的生命周期内多次调用UIViewController(例如,如果您收到内存警告并且您的视图不可见,控制器将释放它并在下次需要时重新加载它)。要正确处理此行为,您应该:

A)在创建定时器之前测试定时器是否存在(例如if (myTimer == nil) { /* initialize the timer */ }

或者

B) Clear the timer in your viewDidUnload method. (This is probably more along the lines of what you want since you most likely don't want the timer to fire events related to an invisible view).

于 2012-04-30T21:02:14.160 回答
0

Set the target for the NSTimer to be a weak self variable, like this:

__weak Object *weakSelf = self;
[NSTimer scheduledTimerWithTimeInterval:5.f target:weakSelf selector:@selector(actionMethod) userInfo:nil repeats:YES];

That will prevent the action being called multiple times.

于 2013-12-10T22:10:47.543 回答