這可能會回答你的問題有關NSTimer real-time behavior:
計時器不是實時的機制;只有在添加了定時器的運行循環模式之一運行並且能夠檢查定時器的觸發時間是否已過時,它纔會觸發。由於典型的運行循環管理各種輸入源,所以定時器的時間間隔的有效分辨率被限制在50-100毫秒的量級上。如果在長時間標註期間發生定時器的觸發時間,或者運行循環處於未監視定時器的模式下,定時器將在下次運行循環檢查定時器時才觸發。因此,計時器觸發的實際時間可能是計劃的點火時間之後的相當長的一段時間。
你不指定要如何調度的NSTimer,但如果你將其排定的NSRunLoopCommonModes
代替NSRunLoopDefaultModes
你可能會發現其性能有所改善:
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
如果不能改善的事情,那麼你應該尋找更低層次的選擇。
特別是,你可能會考慮CADisplayLink
:
一個CADisplayLink對象是一個計時器對象,它允許您的應用程序其繪圖同步到顯示器的刷新速率。
它可以以與NSTimer非常相似的方式使用。
CADisplayLink的優點是鏈接到刷新率,所以它應該在1/60秒的時間間隔內提供非常可靠的行爲。
使用CADisplayLink的示例:
CADisplayLink* displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(respondToTimer)];
[displayLink setFrameInterval:60];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
這將調用respondTimer
各60個刷新幀,即,每秒一次。既然你想讓你的方法只被稱爲一個,你可以使用:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC),
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self respondToTimer];
});
它可能會更容易爲你。 (當然,您可以用該方法的完整實現來替換對[self respondToTimer]的調用)。
我認爲這篇博文可能會回答你的一些問題:http:// atastypixel。com/blog/experimental-with-precise-timing-in-ios/ – 2012-07-16 14:28:02
嘗試使用dispatch_after而不是 – Felix 2012-07-16 14:30:07
調用多長時間後? – 2012-07-16 14:33:41