Dispatch Source Timer的使用及注意事項介紹
前言
Dispatch Source Timer 是一種與 Dispatch Queue 結(jié)合使用的定時器。當(dāng)需要在后臺 queue 中定期執(zhí)行任務(wù)的時候,使用 Dispatch Source Timer 要比使用 NSTimer 更加自然,也更加高效(無需在 main queue 和后臺 queue 之前切換)。下面將詳細(xì)給大家介紹關(guān)于Dispatch Source Timer的使用和一些注意事項,話不多說了,來一起看看詳細(xì)的介紹吧。
創(chuàng)建 Timer
Dispatch Source Timer 首先其實是 Dispatch Source 的一種,關(guān)于 Dispatch Source 的內(nèi)容在這里就不再贅述了。下面是蘋果官方文檔里給出的創(chuàng)建 Dispatch Timer 的代碼:
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; }
有幾個地方需要注意:
- Dispatch Source Timer 是間隔定時器,也就是說每隔一段時間間隔定時器就會觸發(fā)。在 NSTimer 中要做到同樣的效果需要手動把 repeats 設(shè)置為 YES。
- dispatch_source_set_timer 中第二個參數(shù),當(dāng)我們使用dispatch_time 或者 DISPATCH_TIME_NOW 時,系統(tǒng)會使用默認(rèn)時鐘來進(jìn)行計時。然而當(dāng)系統(tǒng)休眠的時候,默認(rèn)時鐘是不走的,也就會導(dǎo)致計時器停止。使用 dispatch_walltime 可以讓計時器按照真實時間間隔進(jìn)行計時。
- dispatch_source_set_timer 的第四個參數(shù) leeway 指的是一個期望的容忍時間,將它設(shè)置為 1 秒,意味著系統(tǒng)有可能在定時器時間到達(dá)的前 1 秒或者后 1 秒才真正觸發(fā)定時器。在調(diào)用時推薦設(shè)置一個合理的 leeway 值。需要注意,就算指定 leeway 值為 0,系統(tǒng)也無法保證完全精確的觸發(fā)時間,只是會盡可能滿足這個需求。
- event handler block 中的代碼會在指定的 queue 中執(zhí)行。當(dāng) queue 是后臺線程的時候,dispatch timer 相比 NSTimer 就好操作一些了。因為 NSTimer 是需要 Runloop 支持的,如果要在后臺 dispatch queue 中使用,則需要手動添加 Runloop。使用 dispatch timer 就簡單很多了。
- dispatch_source_set_event_handler 這個函數(shù)在執(zhí)行完之后,block 會立馬執(zhí)行一遍,后面隔一定時間間隔再執(zhí)行一次。而 NSTimer 第一次執(zhí)行是到計時器觸發(fā)之后。這也是和 NSTimer 之間的一個顯著區(qū)別。
停止 Timer
停止 Dispatch Timer 有兩種方法,一種是使用 dispatch_suspend,另外一種是使用 dispatch_source_cancel。
dispatch_suspend 嚴(yán)格上只是把 Timer 暫時掛起,它和 dispatch_resume 是一個平衡調(diào)用,兩者分別會減少和增加 dispatch 對象的掛起計數(shù)。當(dāng)這個計數(shù)大于 0 的時候,Timer 就會執(zhí)行。在掛起期間,產(chǎn)生的事件會積累起來,等到 resume 的時候會融合為一個事件發(fā)送。
需要注意的是:dispatch source 并沒有提供用于檢測 source 本身的掛起計數(shù)的 API,也就是說外部不能得知一個 source 當(dāng)前是不是掛起狀態(tài),在設(shè)計代碼邏輯時需要考慮到這一點。
dispatch_source_cancel 則是真正意義上的取消 Timer。被取消之后如果想再次執(zhí)行 Timer,只能重新創(chuàng)建新的 Timer。這個過程類似于對 NSTimer 執(zhí)行 invalidate。
關(guān)于取消 Timer,另外一個很重要的注意事項:dispatch_suspend 之后的 Timer,是不能被釋放的!下面的代碼會引起崩潰:
- (void)stopTimer { dispatch_suspend(_timer); _timer = nil; // EXC_BAD_INSTRUCTION 崩潰 }
因此使用 dispatch_suspend 時,Timer 本身的實例需要一直保持。使用 dispatch_source_cancel 則沒有這個限制:
- (void)stopTimer { dispatch_source_cancel(_timer); _timer = nil; // OK }
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
IOS 開發(fā)之 UITextField限制字?jǐn)?shù)的方法
這篇文章主要介紹了IOS 開發(fā)之 UITextField限制字?jǐn)?shù)的方法的相關(guān)資料,這里提供實現(xiàn)限制最大字?jǐn)?shù)的方法,需要的朋友可以參考下2017-08-08iOS實現(xiàn)不規(guī)則Button點擊效果實例代碼
這篇文章主要給大家介紹了關(guān)于iOS實現(xiàn)不規(guī)則Button點擊的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對各位iOS開發(fā)者們具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04ios 不支持 iframe 的完美解決方法(兼容iOS&安卓)
下面小編就為大家?guī)硪黄猧os 不支持 iframe 的完美解決方法(兼容iOS&安卓)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07