在“秒表式”应用程序中,在NSTimer期间0:02一致的1秒长滞后

时间:2011-05-12 18:02:00

标签: iphone timer nsdate nstimer stopwatch

我的应用程序使用秒表样式从0开始以HH:mm:ss格式计数。代码看起来非常简单,我想不出更有效的方式来运行它。

出于某种原因,当我运行它时,当计时器到达00:00:02时,有一个非常明显且一致的(每次我在同一个地方运行它)滞后。它在00:00:02停留一整秒,然后正常计数。为什么会这样?

-(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 release];
    timerLabel.text = timeString;
}

2 个答案:

答案 0 :(得分:1)

NSTimer不会按照确切的时间或时间间隔触发(检查可能的错误的规格)。因此,在相同的时钟秒内可以进行一次后期射击和一次早期射击,当四舍五入到最接近的秒时,您将看到口吃效果。

相反,使用更快的计时器(或CADisplaylink),比如说30赫兹,检查时间,并且只有在时间变得足以改变标签(一秒钟)时才更新标签。

答案 1 :(得分:0)

你要经过的时间间隔是几秒钟:

  

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

我的猜测是,它会被立即调用,之后每1秒调用一次,因为你的定时器间隔是1秒。尝试传递类似1.0 / 20.0的内容以更高的帧速率进行更新。