1.NSTimer 存在一定的誤差,不管是一次性的還是周期性的timer得實際觸發事件的時間,都會與所加入的runloop和runloopMode有關,如果此runloop正在執行一個連續性的運算,timer就會被延時觸發。 2.CADisplayLink CADisplayLink是一個能讓我們以 ...
1.NSTimer
存在一定的誤差,不管是一次性的還是周期性的timer得實際觸發事件的時間,都會與所加入的runloop和runloopMode有關,如果此runloop正在執行一個連續性的運算,timer就會被延時觸發。
// 創建方式1
NSTimer *timer1 = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(action:) userInfo:nil repeats:YES];
[timer1 invalidate];
// 創建方式2==>推薦
NSTimer *timer2 = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(action:) userInfo:nil repeats:YES];
// 加入運行迴圈
[[NSRunLoop mainRunLoop] addTimer:timer2 forMode:NSDefaultRunLoopMode];
[timer2 invalidate];
2.CADisplayLink
CADisplayLink是一個能讓我們以和屏幕刷新率同步的頻率將特定的內容畫到屏幕上的定時器類。CADisplayLink以特定模式註冊到runloop後,每當屏幕顯示內容刷新結束的時候,runloop就會向CADisplayLink指定的target發送一次指定的selector消息,CADisplayLink類對應的selector就會被調用一次。
iOS設備的屏幕刷新頻率是固定的,CADisplayLink在正常情況下會再每次刷新結束後都被調用,精確度相當高。使用場合相對專一,適合做UI的不同重繪,比如自定義動畫引擎或者視頻播放的渲染。不需要在格外關心屏幕的刷新頻率了,本身就是跟屏幕刷新同步的。
//創建對象
CADisplayLink *display = [CADisplayLink displayLinkWithTarget:self selector:@selector(action:)];
//加入當前迴圈
[display addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
//銷毀
[display invalidate];
3.GCD
NSTimer是在runloop的基礎上執行的,然而runloop是在GCD的基礎上實現的,所以說GCD可算是更加高級的。
// 獲得隊列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
// 創建一個定時器
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
// 設置定時器
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1000 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
dispatch_source_set_event_handler(timer, ^{
// 觸發事件
// 取消定時器
dispatch_cancel(timer);
});
// 啟動定時器
dispatch_resume(timer);