溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

ios中Dispatch Source Timer怎么用

發(fā)布時(shí)間:2021-08-09 11:36:16 來源:億速云 閱讀:130 作者:小新 欄目:移動(dòng)開發(fā)

小編給大家分享一下ios中Dispatch Source Timer怎么用,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

創(chuàng)建 Timer

Dispatch Source Timer 首先其實(shí)是 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;
}

有幾個(gè)地方需要注意:

  1. Dispatch Source Timer 是間隔定時(shí)器,也就是說每隔一段時(shí)間間隔定時(shí)器就會(huì)觸發(fā)。在 NSTimer 中要做到同樣的效果需要手動(dòng)把 repeats 設(shè)置為 YES。

  2. dispatch_source_set_timer 中第二個(gè)參數(shù),當(dāng)我們使用dispatch_time 或者 DISPATCH_TIME_NOW 時(shí),系統(tǒng)會(huì)使用默認(rèn)時(shí)鐘來進(jìn)行計(jì)時(shí)。然而當(dāng)系統(tǒng)休眠的時(shí)候,默認(rèn)時(shí)鐘是不走的,也就會(huì)導(dǎo)致計(jì)時(shí)器停止。使用 dispatch_walltime 可以讓計(jì)時(shí)器按照真實(shí)時(shí)間間隔進(jìn)行計(jì)時(shí)。

  3. dispatch_source_set_timer 的第四個(gè)參數(shù) leeway 指的是一個(gè)期望的容忍時(shí)間,將它設(shè)置為 1 秒,意味著系統(tǒng)有可能在定時(shí)器時(shí)間到達(dá)的前 1 秒或者后 1 秒才真正觸發(fā)定時(shí)器。在調(diào)用時(shí)推薦設(shè)置一個(gè)合理的 leeway 值。需要注意,就算指定 leeway 值為 0,系統(tǒng)也無法保證完全精確的觸發(fā)時(shí)間,只是會(huì)盡可能滿足這個(gè)需求。

  4. event handler block 中的代碼會(huì)在指定的 queue 中執(zhí)行。當(dāng) queue 是后臺(tái)線程的時(shí)候,dispatch timer 相比 NSTimer 就好操作一些了。因?yàn)?NSTimer 是需要 Runloop 支持的,如果要在后臺(tái) dispatch queue 中使用,則需要手動(dòng)添加 Runloop。使用 dispatch timer 就簡(jiǎn)單很多了。

  5. dispatch_source_set_event_handler 這個(gè)函數(shù)在執(zhí)行完之后,block 會(huì)立馬執(zhí)行一遍,后面隔一定時(shí)間間隔再執(zhí)行一次。而 NSTimer 第一次執(zhí)行是到計(jì)時(shí)器觸發(fā)之后。這也是和 NSTimer 之間的一個(gè)顯著區(qū)別。

停止 Timer

停止 Dispatch Timer 有兩種方法,一種是使用 dispatch_suspend,另外一種是使用 dispatch_source_cancel。

dispatch_suspend 嚴(yán)格上只是把 Timer 暫時(shí)掛起,它和 dispatch_resume 是一個(gè)平衡調(diào)用,兩者分別會(huì)減少和增加 dispatch 對(duì)象的掛起計(jì)數(shù)。當(dāng)這個(gè)計(jì)數(shù)大于 0 的時(shí)候,Timer 就會(huì)執(zhí)行。在掛起期間,產(chǎn)生的事件會(huì)積累起來,等到 resume 的時(shí)候會(huì)融合為一個(gè)事件發(fā)送。

需要注意的是:dispatch source 并沒有提供用于檢測(cè) source 本身的掛起計(jì)數(shù)的 API,也就是說外部不能得知一個(gè) source 當(dāng)前是不是掛起狀態(tài),在設(shè)計(jì)代碼邏輯時(shí)需要考慮到這一點(diǎn)。

dispatch_source_cancel 則是真正意義上的取消 Timer。被取消之后如果想再次執(zhí)行 Timer,只能重新創(chuàng)建新的 Timer。這個(gè)過程類似于對(duì) NSTimer 執(zhí)行 invalidate。

關(guān)于取消 Timer,另外一個(gè)很重要的注意事項(xiàng):dispatch_suspend 之后的 Timer,是不能被釋放的!下面的代碼會(huì)引起崩潰:

- (void)stopTimer
{
 dispatch_suspend(_timer);
 _timer = nil; // EXC_BAD_INSTRUCTION 崩潰
}

因此使用 dispatch_suspend 時(shí),Timer 本身的實(shí)例需要一直保持。使用 dispatch_source_cancel 則沒有這個(gè)限制:

- (void)stopTimer
{
 dispatch_source_cancel(_timer);
 _timer = nil; // OK
}

以上是“ios中Dispatch Source Timer怎么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI