我必须定期(每0.16秒)发射一次方法。容差可以说,高达30%。接近16毫秒,更好。
我已经尝试过NSTimers,但它们不够精确。我尝试了线程,也遇到了同样的问题。我正在尝试派遣计时器。
我使用的是Apple提供的代码:
dispatch_source_t CreateDispatchTimer(uint64_t interval,
uint64_t leeway,
dispatch_queue_t queue,
dispatch_block_t block)
{
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,
0, 0, queue);
if (timer)
{
dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), interval, leeway);
dispatch_source_set_event_handler(timer, block);
dispatch_resume(timer);
}
return timer;
}
void MyCreateTimer()
{
dispatch_source_t aTimer = CreateDispatchTimer(0.16 * NSEC_PER_SEC, //0.16 ms
0.048 * NSEC_PER_SEC, //30% tolerance
dispatch_get_main_queue(),
^{ MyPeriodicTask(); });
// Store it somewhere for later use.
if (aTimer)
{
MyStoreTimer(aTimer);
}
}
我正在测量间隔并在执行MyPeriodicTask()之间获得这些时间:
0.148, 0.165, 0.148, 0.167, 0.167, 0.187, 0.167,
0.167, 0.146, 0.166, 0.167, 0.167, 0.188, 0.145,
0.243, 0.331, 0.047, 0.045, 0.168, 0.165, 0.167,
0.166, 0.167, 0.167, 0.169, 0.165, 0.166, 0.169,
0.165, 0.203, 0.130, 0.167, 0.167, 0.167, 0.167,
0.167, 0.167, 0.167, 0.167, 0.167
请注意,该方法在16ms范围内或多或少地被触发。
考虑到30%的范围,我预计值在0.118和0.214毫秒之间,但注意值远远高于该范围的0.243和0.331以及其他如0.047和0.045!该方法如何在定时器间隔之前触发???
可能发生什么?有没有办法在iPhone上精确执行定时方法???
感谢。
答案 0 :(得分:6)
dispatch_source_t aTimer = CreateDispatchTimer(0.16 * NSEC_PER_SEC, //0.16 ms
0.048 * NSEC_PER_SEC, //30% tolerance
dispatch_get_main_queue(),
^{ MyPeriodicTask(); });
您正在使用主队列来触发该功能。这意味着该函数是从主线程上的RunLoop执行的。执行时间取决于RunLoop的任务。如果MyPeriodicTask能够在后台线程上执行,请使用Global Queue而不是Main Queue。
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)
尽管如此,即使使用Global Queue,它也可能不稳定。我认为CADisplayLink更稳定。
幸运的是,CADisplayLink的帧速率在iOS上为60fps。它等于你想要的16.6ms。