Darren
Darren

Reputation: 10398

NSTimer won't invalidate on iPad but works fine on iPhone

I have a repeating timer that runs down a clock. During the clock running down I call stopTimer and the clock should stop. This has worked 100% on the iPhone however on the iPad it will sometimes fail to stop the timer. This happens about 50% of the time. The NSLog's are called in the stop method.

Here's my timer code:

- (void)startSliderTimer
{
    // Get start time
    [self stopTimer];
    startTime = [NSDate timeIntervalSinceReferenceDate] + kmaxTimePerSlider;
    self.timer = [NSTimer scheduledTimerWithTimeInterval:0.01f target:self selector:@selector(updateClock) userInfo:nil repeats:YES];
}

- (void)updateClock
{
    NSTimeInterval currentTimer = [NSDate timeIntervalSinceReferenceDate];
    NSTimeInterval currentTimeLeft = startTime - currentTimer;
    if (currentTimeLeft >= 0) {
        int seconds = currentTimeLeft;
        float milliseconds = currentTimeLeft - seconds;
        int mill = milliseconds * 1000;
        NSString* displayTime = [NSString stringWithFormat: @"%02d:%03d",seconds,mill];
        timerLbl.text = displayTime;
    } else {
        [self tooSlow];
    }
}

- (void) stopTimer
{
    NSLog(@"%s",__FUNCTION__);
    if (self.timer) {
        NSLog(@"Stop Timer");
        [self.timer invalidate];
        self.timer = nil;
    }
}

I have just tried running the timer like this as suggestion in another question/answer but it still doesn't always invalidate:

self.timer = [NSTimer timerWithTimeInterval:0.01f target:self selector:@selector(updateClock) userInfo:nil repeats:YES];
    [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];

Upvotes: 1

Views: 405

Answers (2)

Nicolas Miari
Nicolas Miari

Reputation: 16246

For a game, perhaps you should use CADisplayLink instead of NSTimer.

Upvotes: 0

kevboh
kevboh

Reputation: 5245

Create the timer without scheduling it using a +timerWith... method, then schedule it on the runloop yourself using [[NSRunLoop currentRunLoop] addTimer:timer forMode: NSRunLoopCommonModes] to run it on all runloops. Let me know if that works.

Upvotes: 1

Related Questions