开发者

Consistent 1-Second-Long lag at 0:02 during NSTimer in "stopwatch-like" app

I have an app that uses a stopwatch-style count up from 0 in HH:mm:ss format. The code looks pretty straightforward to me, and I can't think of a more efficient way to run it.

For some reason, when I run it, there is a very noticeable and consistent (every time I run it, in the same place) lag when the timer gets to 00:00:02. It stays on 00:00:02 for a full second, and then counts on normally. Why would this happen?

-(IBAction)startAndStop;
{
if (!timer) {
    NSLog(@"Pressing Start Button");
    [startAndStopButton setTitle:@"Stop" forState:0];
    startDate = [[NSDate date] retain];
    timerLabel.text = @"00:00:00";
    timer = [NSTimer scheduledTimerWithTimeInterval:1 
                                             target:self
                                           selector:@selector(timerStart) 
                                           userInfo:nil 
                                            repeats:YES];

    } else {

    NSLog(@"Pressing Stop Button");
    [startAndStopButton setTitle:@"Start" forState:0];
    [startDate release];
    [timer invalidate];
    timer = nil;
    [timer release];
    }
}

-(void)timerStart
{
    NSDate *currentDate = [NSDate date];
    NSTimeInterval countInSeconds = [currentDate timeIntervalSinceDate:startDate];
    NSDate *timerDate = [NSDate dateWithTimeIntervalSinceReferenceDate:countInSeconds];

    NSDateFormatter *df = [[NSDateFormatter alloc] init];
    [df setDateFormat:@"HH:mm:ss"];
    [df setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
    NSString *timeString = [df stringFromDate:timerDate];
    [df relea开发者_开发技巧se];
    timerLabel.text = timeString;
}


NSTimer does not fire at exact times or time intervals (check the specification for the likely error). Thus it is possible for one late firing and one early firing to occur during the same clock second, when rounded to the nearest second, and you will see a stutter effect.

Instead, use a much faster timer (or CADisplaylink), say at 30 Hz, check the time, and update the label only if the time has changed enough to change the label (one second).


The interval you are passing is in seconds:

http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSTimer_Class/Reference/NSTimer.html

My guess is that it is getting called immediately, and then every 1 second afterwards, since you are passing 1 second as the timer interval. Try passing something like 1.0/20.0 to update at a higher frame rate.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜