1.NSTimer
存在一定的誤差搬泥,不管是一次性的還是周期性的timer得實際觸發(fā)事件的時間,都會與所加入的runloop和runloopMode有關(guān),如果此runloop正在執(zhí)行一個連續(xù)性的運算,timer就會被延時觸發(fā)愧怜。
// 創(chuàng)建方式1
NSTimer *timer1 = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(action:) userInfo:nil repeats:YES];
[timer1 invalidate];
// 創(chuàng)建方式2==>推薦
NSTimer *timer2 = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(action:) userInfo:nil repeats:YES];
// 加入運行循環(huán)
[[NSRunLoop mainRunLoop] addTimer:timer2 forMode:NSDefaultRunLoopMode];
[timer2 invalidate];
2.CADisplayLink
CADisplayLink是一個能讓我們以和屏幕刷新率同步的頻率將特定的內(nèi)容畫到屏幕上的定時器類。CADisplayLink以特定模式注冊到runloop后妈拌,每當屏幕顯示內(nèi)容刷新結(jié)束的時候拥坛,runloop就會向CADisplayLink指定的target發(fā)送一次指定的selector消息,CADisplayLink類對應(yīng)的selector就會被調(diào)用一次尘分。
iOS設(shè)備的屏幕刷新頻率是固定的渴逻,CADisplayLink在正常情況下會再每次刷新結(jié)束后都被調(diào)用,精確度相當高音诫。使用場合相對專一惨奕,適合做UI的不同重繪,比如自定義動畫引擎或者視頻播放的渲染竭钝。不需要在格外關(guān)心屏幕的刷新頻率了梨撞,本身就是跟屏幕刷新同步的。
//創(chuàng)建對象
CADisplayLink *display = [CADisplayLink displayLinkWithTarget:self selector:@selector(action:)];
//加入當前循環(huán)
[display addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
//銷毀
[display invalidate];
3.GCD
NSTimer是在runloop的基礎(chǔ)上執(zhí)行的香罐,然而runloop是在GCD的基礎(chǔ)上實現(xiàn)的卧波,所以說GCD可算是更加高級的。
// 獲得隊列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
// 創(chuàng)建一個定時器
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
// 設(shè)置定時器
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1000 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
dispatch_source_set_event_handler(timer, ^{
// 觸發(fā)事件
// 取消定時器
dispatch_cancel(timer);
});
// 啟動定時器
dispatch_resume(timer);