項目里用到定時器時,看同事是這么寫的:
@property (nonatomic,strong) dispatch_source_t timer;
if (!self.timer) {
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC));
uint64_t interval = (uint64_t)(1 * NSEC_PER_SEC);
dispatch_source_set_timer(self.timer, start, interval, 0);
dispatch_source_set_event_handler(self.timer, ^{
// NSLog(@"定時器開啟中........");
dispatch_async(dispatch_get_main_queue(), ^{
// 主線程添加事件處理
});
});
//啟動定時器
dispatch_resume(self.timer);
}
/**
* 移除定時器
*/
- (void)removeTimer {
if (self.timer) {
dispatch_source_cancel(self.timer);
self.timer = nil;
}
}
跟自己寫的NSTimer檔次不一樣巍糯,感覺這個逼格好高啊齿穗,然后就研究了下 dispatch_sourcer在定時器里的使用,如下喊括。
定時器dispatch source定時產(chǎn)生事件胧瓜,可以用來發(fā)起定時執(zhí)行的任務(wù),所有定時器dispatch source都是間隔定時器郑什,一旦創(chuàng)建府喳,會按你指定的間隔定期遞送事件。你需要為定時器dispatch source指定一個期望的定時器事件精度蘑拯,也就是leeway值钝满,讓系統(tǒng)能夠靈活地管理電源并喚醒內(nèi)核。例如系統(tǒng)可以使用leeway值來提前或延遲觸發(fā)定時器申窘,使其更好地與其它系統(tǒng)事件結(jié)合弯蚜。創(chuàng)建自己的定時器時,你應(yīng)該盡量指定一個leeway值剃法。
就算你指定leeway值為0碎捺,也不要期望定時器能夠按照精確的納秒來觸發(fā)事件。系統(tǒng)會盡可能地滿足你的需求玄窝,但是無法保證完全精確的觸發(fā)時間牵寺。
當計算機睡眠時,定時器dispatch source會被掛起恩脂,稍后系統(tǒng)喚醒時帽氓,定時器dispatch source也會自動喚醒。根據(jù)你提供的配置俩块,暫停定時器可能會影響定時器下一次的觸發(fā)黎休。如果定時器dispatch source使用 dispatch_time 函數(shù)或DISPATCH_TIME_NOW 常量設(shè)置浓领,定時器dispatch source會使用系統(tǒng)默認時鐘來確定何時觸發(fā),但是默認時鐘在計算機睡眠時不會繼續(xù)势腮。
如果你使用dispatch_walltime函數(shù)來設(shè)置定時器dispatch source联贩,則定時器會根據(jù)掛鐘時間來跟蹤,這種定時器比較適合觸發(fā)間隔相對比較大的場合捎拯,可以防止定時器觸發(fā)間隔出現(xiàn)太大的誤差泪幌。
下面是定時器dispatch source的一個例子,每30秒觸發(fā)一次署照,leeway值為1祸泪,因為間隔相對較大,使用 dispatch_walltime 來創(chuàng)建定時器建芙。定時器會立即觸發(fā)第一次没隘,隨后每30秒觸發(fā)一次。MyPeriodicTask 和 MyStoreTimer 是自定義函數(shù)禁荸,用于實現(xiàn)定時器的行為右蒲,并存儲定時器到應(yīng)用的數(shù)據(jù)結(jié)構(gòu)。
dispatch_source_t CreateDispatchTimer(uint64_t interval,
uint64_t leeway,
dispatch_queue_t queue,
dispatch_block_t block)
{
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,
0, 0, queue);
if (timer)
{
dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), interval, leeway);
dispatch_source_set_event_handler(timer, block);
dispatch_resume(timer);
}
return timer;
}
void MyCreateTimer()
{
dispatch_source_t aTimer = CreateDispatchTimer(30ull * NSEC_PER_SEC,
1ull * NSEC_PER_SEC,
dispatch_get_main_queue(),
^{ MyPeriodicTask(); });
// Store it somewhere for later use.
if (aTimer)
{
MyStoreTimer(aTimer);
}
}
雖然定時器dispatch source是接收時間事件的主要方法赶熟,你還可以使用其它選擇瑰妄。如果想在指定時間間隔后執(zhí)行一個block,可以使用 dispatch_after 或 dispatch_after_f函數(shù)映砖。這兩個函數(shù)非常類似于dispatch_async翰撑,但是只允許你指定一個時間值,時間一到就自動提交block到queue中執(zhí)行啊央,時間值可以指定為相對或絕對時間。
然后我總結(jié)了下用dispatch_source寫定時器的優(yōu)缺點
優(yōu)點:
1涨醋、可以暫停瓜饥,繼續(xù)。 不用像NSTimer一樣需要重新創(chuàng)建浴骂。
2乓土、性能較好。
缺點:
1溯警、每次resume都會先執(zhí)行一次趣苏。
共同點:
1、如果不手動釋放就不會走dealloc梯轻。
2食磕、不精確