最近我一直在使用dispatch_after而不是performSelector:withObject:afterDelay,当我想在延迟后触发一些代码.代码更清晰,它可以访问封闭的范围,我可以将代码放入内联而不是写一个抛弃方法等等.
我的代码可能如下所示:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
delay * NSEC_PER_SEC),
dispatch_get_main_queue(),
^{
//Delayed-execution code goes here.
}
);
Run Code Online (Sandbox Code Playgroud)
但是,我最近发现这段代码的执行时间似乎比请求的速度慢了大约10%.如果我要求延迟10秒,我的块将在11秒后执行.这是在iOS设备上.时间似乎在模拟器上非常接近.
我用来测试它的代码非常简单:
NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
delay * NSEC_PER_SEC),
dispatch_get_main_queue(),
^{
NSTimeInterval actualDelay = [NSDate timeIntervalSinceReferenceDate] - startTime;
NSLog(@"Requested delay = %.3f. Atual delay = %.3f", delay, actualDelay);
//Delayed-execution code goes here.
}
);
Run Code Online (Sandbox Code Playgroud)
我已经在从iOS 4S到iPad Air的设备上进行了测试,而且额外的延迟非常一致.我还没有在像iPhone 4或iPad 2这样的旧设备上进行测试,尽管我很快就会这样做.
我可能期望在延迟中有20-50毫秒的"斜率",但是一致的10% - 11%的超调是奇怪的.
我在我的代码中添加了一个"软糖因子"来调整额外的延迟,但我发现它令人惊讶:
#define delay_fudge 0.912557 //Value calculated based on averages from testing.
NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
delay * delay_fudge * NSEC_PER_SEC), …Run Code Online (Sandbox Code Playgroud)