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