GCD計(jì)時(shí)器

大家在開(kāi)發(fā)的過(guò)程中,經(jīng)常會(huì)用到定時(shí)器,通常的做法可能就是NSTimer,了解過(guò)GCD的同學(xué)可能會(huì)接觸到dispatch source的概念,dispatch source是一個(gè)監(jiān)視某些類型事件的對(duì)象。當(dāng)這些事件發(fā)生時(shí),它自動(dòng)將一個(gè)block放入一個(gè)dispatch queue的執(zhí)行例程中。

dispatch source支持的事件有很多,__MAC_10_6支持的事件如下:(請(qǐng)參考source.h

*  DISPATCH_SOURCE_TYPE_DATA_ADD:        n/a

*  DISPATCH_SOURCE_TYPE_DATA_OR:        n/a

*  DISPATCH_SOURCE_TYPE_MACH_SEND:      mach port (mach_port_t)

*  DISPATCH_SOURCE_TYPE_MACH_RECV:      mach port (mach_port_t)

*  DISPATCH_SOURCE_TYPE_MEMORYPRESSURE  n/a

*  DISPATCH_SOURCE_TYPE_PROC:            process identifier (pid_t)

*  DISPATCH_SOURCE_TYPE_READ:            file descriptor (int)

*  DISPATCH_SOURCE_TYPE_SIGNAL:          signal number (int)

*  DISPATCH_SOURCE_TYPE_TIMER:          n/a

*  DISPATCH_SOURCE_TYPE_VNODE:          file descriptor (int)

*  DISPATCH_SOURCE_TYPE_WRITE:          file descriptor (int)

這里主要說(shuō)一下計(jì)時(shí)器,對(duì)其他事件感興趣的同學(xué)可以網(wǎng)上查些資料。

GCD計(jì)時(shí)器的使用通常由一下幾個(gè)函數(shù)構(gòu)成:

1.dispatch_source_create

創(chuàng)建一個(gè)新的調(diào)度源來(lái)監(jiān)視低級(jí)別的系統(tǒng)對(duì)象和自動(dòng)提交處理程序塊來(lái)響應(yīng)事件調(diào)度隊(duì)列

2.dispatch_source_set_timer

為一個(gè)定時(shí)源設(shè)置一個(gè)開(kāi)始時(shí)間、事件間隔、誤差值

我們來(lái)看看這個(gè)函數(shù)原型

dispatch_source_set_timer(dispatch_source_t source,
                          dispatch_time_t start,
                          uint64_t interval,
                          uint64_t leeway);

source當(dāng)然就是我們第一步創(chuàng)建的調(diào)度源。

start是我們?cè)O(shè)定的計(jì)時(shí)開(kāi)始時(shí)間,可以dispatch_timedispatch_walltime 函數(shù)來(lái)創(chuàng)建它們,至于dispatch_timedispatch_walltime的區(qū)別,stackoverflow的解釋是這樣的

dispatch_time stops running when your computer goes to sleep. dispatch_walltime continues running. So if you want to do an action in one hour minutes, but after 5 minutes your computer goes to sleep for 50 minutes, dispatch_walltime will execute an hour from now, 5 minutes after the computer wakes up. dispatch_time will execute after the computer is running for an hour, that is 55 minutes after it wakes up.

但是我自己在iPhone上測(cè)試的時(shí)候好像并沒(méi)有什么卵用,難道是Mac跟iPhone的機(jī)制不一樣?有興趣的同學(xué)可以去深究一下,找到答案可以告訴我一下。

interval就是時(shí)間間隔了,這個(gè)不用多說(shuō)了。

leeway,對(duì)這個(gè)參數(shù)的理解,我覺(jué)得http://www.dreamingwish.comSeven's同學(xué)的解釋很直觀也很易懂:
“這個(gè)參數(shù)告訴系統(tǒng)我們需要計(jì)時(shí)器觸發(fā)的精準(zhǔn)程度。所有的計(jì)時(shí)器都不會(huì)保證100%精準(zhǔn),這個(gè)參數(shù)用來(lái)告訴系統(tǒng)你希望系統(tǒng)保證精準(zhǔn)的努力程度。如果你希望一個(gè)計(jì)時(shí)器沒(méi)五秒觸發(fā)一次,并且越準(zhǔn)越好,那么你傳遞0為參數(shù)。另外,如果是一個(gè)周期性任務(wù),比如檢查email,那么你會(huì)希望每十分鐘檢查一次,但是不用那么精準(zhǔn)。所以你可以傳入60,告訴系統(tǒng)60秒的誤差是可接受的。這樣有什么意義呢?簡(jiǎn)單來(lái)說(shuō),就是降低資源消耗。如果系統(tǒng)可以讓cpu休息足夠長(zhǎng)的時(shí)間,并在每次醒來(lái)的時(shí)候執(zhí)行一個(gè)任務(wù)集合,而不是不斷的醒來(lái)睡去以執(zhí)行任務(wù),那么系統(tǒng)會(huì)更高效。如果傳入一個(gè)比較大的leeway給你的計(jì)時(shí)器,意味著你允許系統(tǒng)拖延你的計(jì)時(shí)器來(lái)將計(jì)時(shí)器任務(wù)與其他任務(wù)聯(lián)合起來(lái)一起執(zhí)行?!?/p>

3.dispatch_source_set_event_handler

給一個(gè)調(diào)度源設(shè)置一個(gè)時(shí)間處理塊。

4.dispatch_source_cancel

異步取消一個(gè)調(diào)度源,防止任何進(jìn)一步調(diào)用它的事件處理塊的發(fā)生

5.dispatch_source_set_cancel_handler

給一個(gè)調(diào)度源設(shè)置一個(gè)取消處理塊

6.dispatch_resume

同步等待一個(gè)對(duì)象,直到超時(shí)

以上幾個(gè)步驟中,dispatch_source_set_event_handler與dispatch_source_cancel必須一起出現(xiàn),否則調(diào)度源處理塊不會(huì)執(zhí)行。

下面附一段完整的代碼,演示一個(gè)簡(jiǎn)單的10秒倒計(jì)時(shí)的功能:

- (void)start
{
    __block int32_t timeOutCount=10;
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
    
    dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1ull * NSEC_PER_SEC, 0);
    dispatch_source_set_event_handler(timer, ^{
        OSAtomicDecrement32(&timeOutCount);
        if (timeOutCount == 0) {
            NSLog(@"timersource cancel");
            dispatch_source_cancel(timer);
        }
    });
    
    dispatch_source_set_cancel_handler(timer, ^{
        NSLog(@"timersource cancel handle block");
    });
    
    dispatch_resume(timer);
}

備注,記得#import<libkern/OSAtomic.h>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一:base.h 二:block.h 1. dispatch_block_flags:DISPATCH_BLOCK...
    小暖風(fēng)閱讀 2,776評(píng)論 0 0
  • Dispatch Sources 現(xiàn)代系統(tǒng)通常提供異步接口,允許應(yīng)用向系統(tǒng)提交請(qǐng)求,然后在系統(tǒng)處理請(qǐng)求時(shí)應(yīng)用可以繼...
    YangPu閱讀 386評(píng)論 0 0
  • 當(dāng)和底層系統(tǒng)交互時(shí),必須花費(fèi)大量時(shí)間為任務(wù)做好準(zhǔn)備。調(diào)用內(nèi)核或者其他系統(tǒng)層需要切換上下文,這也是比在進(jìn)程內(nèi)部調(diào)用昂...
    坤坤同學(xué)閱讀 1,853評(píng)論 0 16
  • 調(diào)度源 當(dāng)和底層系統(tǒng)交互時(shí),必須花費(fèi)大量時(shí)間為任務(wù)做好準(zhǔn)備。調(diào)用內(nèi)核或者其他系統(tǒng)層需要切換上下文,這也是比在進(jìn)程內(nèi)...
    iOS的Developer閱讀 350評(píng)論 0 0
  • 1.NSTimer不準(zhǔn)時(shí)的原因:(1).RunLoop循環(huán)處理時(shí)間,每次循環(huán)是固定時(shí)間,只有在這段時(shí)間才會(huì)去查看N...
    稻春閱讀 1,360評(píng)論 0 3

友情鏈接更多精彩內(nèi)容