NSTimer是否可以在指定时间之前触发?

时间:2013-05-10 13:54:03

标签: objective-c cocoa nstimer

我一直在使用NSTimers触发我的应用程序中的某些时间敏感的事件(基本上必须在我告诉它们发生时达到第二个分辨率)。但是,我曾经遇到过,有时候,计时器会在之前触发,所以如果我记录计时器触发的日期,它可能会说14:34:59而不是14:35:00。这有点烦人。我在docs搜索了一个解释并发现了这个:

  • 由于各种输入源,典型的运行循环管理, 定时器的时间间隔的有效分辨率限于 大约50-100毫秒。

和此:

  • 如果在长时间标注期间或者在长时间标注期间发生计时器的开火时间 run loop处于一种不监视定时器的模式,即定时器 直到下次运行循环检查计时器时才会触发。

因此定时器的分辨率为100毫秒,这可以解释为什么定时器之前触发,但只有在有意义的情况下。而不是因为人们会认为100毫秒的差异是由延迟引起的,而不是相反。

所以, 1:为什么定时器会在他们的时间之前触发, 2:我该如何避免这种情况?

修改

这就是我计算日期的方式:

  1. 我从一个NSDate对象开始([NSDate now]或来自NSDatePicker的日期)
  2. 我使用NSDateComponents添加日期 x 天数
  3. 我再次使用NSDateComponents
  4. 设置该日期的小时,数量和秒数(但保留第2步的日/月/年)
  5. 我以这种方式设置计时器:

    timer = [NSTimer timerWithTimeInterval:10 target:self selector:@selector(myMethod)userInfo:nil repeats:NO];

    [timer setFireDate:firingDate];

    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

  6. 编辑2:

    我还记录了时间间隔(而不是小时/分钟/秒),它总是x.0000,这意味着它正好在第二个的确切开始,它应该是什么样的(不是之前) ,而不是之后。)

1 个答案:

答案 0 :(得分:2)

您有可能错误地计算时间间隔(秒)。请注意,这是一个NSTimeInterval,定义为double。您是否有机会将时间间隔四舍五入到最接近的秒?在那种情况下,倒圆计时器会过早启动。

编辑:确实有经验证据表明NSTimer可能会提早开火。我的猜测是文档中提到的准确性不只是+而是+/-而且runloop在if(fireDelta>-0.0xxx) then fireNow();的行中做了一些事情。

所以要解决这个问题:

  • 始终在点火时间中添加一个小三角形,并希望三角形足够(丑陋且无法保证)

  • 当计时器触发时,执行if(timer.fireDate.timeIntervalSinceNow>0.0) then并使用相同的fireDate重新安排计时器。还是很难看......