Dispatch Timer

dispatch timer就是一類(lèi)dispatch source:DISPATCH_SOURCE_TYPE_TIMER,并非是一個(gè)單獨(dú)的timer。還有DISPATCH_SOURCE_TYPE_DATA_ADD等共10類(lèi)。這10類(lèi)作用基本都是監(jiān)聽(tīng)事件。只是用法不同,timer是固定時(shí)間觸發(fā)監(jiān)聽(tīng)事件。
DISPATCH_SOURCE_TYPE_DATA_ADD類(lèi)型的源是在調(diào)用dispatch_source_merge_data的時(shí)候觸發(fā)事件,而且它有個(gè)很有意思的特點(diǎn)就是當(dāng)同一時(shí)間,一個(gè)事件的的觸發(fā)頻率很高時(shí),Dispatch Source會(huì)將這些事件以ADD的方式進(jìn)行累積,然后等系統(tǒng)空閑時(shí)最終處理。如果觸發(fā)頻率比較零散,那么Dispatch Source會(huì)將這些事件分別響應(yīng)。
而且這些源都基本的操作都是:1. 創(chuàng)建;2. 分發(fā);3. 掛起;4,取消。
下面開(kāi)始詳細(xì)看下dispatch timer的使用。

創(chuàng)建timer

創(chuàng)建timer的代碼如下:

// 創(chuàng)建timer
  dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
  // 開(kāi)始時(shí)間 
  dispatch_time_t start =  dispatch_time(DISPATCH_TIME_NOW, 1.0*NSEC_PER_SEC);
  // 間隔時(shí)間
  dispatch_time_t interval = 2.0*NSEC_PER_SEC;
  dispatch_source_set_timer(timer,start,interval,1000ull);

注意,在ARC中dispatch_source_t和普通的OC對(duì)象一樣使用,所以timer使用時(shí)不要是局部變量,因?yàn)榫植孔兞繒?huì)立即釋放。要注意timer的生命周期,這個(gè)和NSTimer一樣。需要注意的是dispatch timer中用到的時(shí)間都是納秒,即NSEC_PER_SEC。這里要注意的是dispatch timer沒(méi)有repect參數(shù),如果只想觸發(fā)一次需要把間隔時(shí)間設(shè)置成DISPATCH_TIME_FOREVER。

事件處理

dispatch timer的處理分為兩種:block和函數(shù)指針;

// block形式
dispatch_source_set_event_handler(timer, ^{
    // 這里是一個(gè)無(wú)參數(shù)無(wú)返回值的block
});

上面是block形式,使用時(shí)也要注意循環(huán)引用。這個(gè)和NSTimer是一樣的。仔細(xì)看方法名可以注意到,該方法名與timer是沒(méi)關(guān)系的,也就是其他類(lèi)型的源想要設(shè)置handler也是這樣的。

// 設(shè)置跟隨timer的context
void *context = NULL;
dispacth_set_context(timer,context);
// C類(lèi)型的回調(diào)方法
void funcPointer1(void*arg){//...}
void funcPointer2(void*arg){//...}
// 設(shè)置回調(diào)方法
dispach_source_set_event_handler_f(timer,funcPointer1);
dispach_source_set_cancel_event_handler_f(timer,funcPointer2);

上面是函數(shù)指針的形式。要比block復(fù)雜一點(diǎn)。從下往上看,可以看到可以設(shè)置兩個(gè)回調(diào)方法,分別是事件觸發(fā)和事件取消時(shí)的方法?;卣{(diào)方法是一個(gè)C的函數(shù)指針。函數(shù)指針類(lèi)型如funcPointer1所示。跟隨timer的context是block沒(méi)有的重要的功能。該context會(huì)在事件觸發(fā)時(shí)傳遞給funcPointer1方法。context是一個(gè)void*的指針,可以添加任意多的內(nèi)容。但是注意的是在ARC下結(jié)構(gòu)體內(nèi)部不能有對(duì)象。注意context可能會(huì)造成循環(huán)引用。

分發(fā)事件與停止事件

事件分發(fā)和事件觸發(fā)在這是兩個(gè)完全不同的事。比如timer的事件觸發(fā)是底層mk_timer觸發(fā)的。事件觸發(fā)后能不能分發(fā)是由GCD決定的。再比如DISPATCH_SOURCE_TYPE_DATA_ADD是我們調(diào)用dispatch_source_merge_data觸發(fā)的,能不能分發(fā)也是有GCD決定的。

// 啟動(dòng)分發(fā)事件
dispatch_resume(source);
// 暫停分發(fā)事件
dispacth_suspend(source);
// 取消事件,也就是停止監(jiān)聽(tīng)事件
dispatch_cancel(source);

dispatch_resume事件想要被處理就必須調(diào)用該方法,該方法可以理解成是事件分發(fā)的開(kāi)關(guān)。dispatch_suspend會(huì)暫停事件分發(fā)。暫停期間,所有的事件都會(huì)被丟棄,也就是在此開(kāi)始時(shí)這期間的事件不會(huì)被處理。dispatch_cancel會(huì)停止接收時(shí)間,無(wú)法再開(kāi)始。如果強(qiáng)行掉resumen會(huì)crash!

?著作權(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)容

  • Dispatch Sources 現(xiàn)代系統(tǒng)通常提供異步接口,允許應(yīng)用向系統(tǒng)提交請(qǐng)求,然后在系統(tǒng)處理請(qǐng)求時(shí)應(yīng)用可以繼...
    好雨知時(shí)節(jié)浩宇閱讀 3,908評(píng)論 2 5
  • 支持原創(chuàng) 現(xiàn)代系統(tǒng)通常提供異步接口,允許應(yīng)用向系統(tǒng)提交請(qǐng)求,然后在系統(tǒng)處理請(qǐng)求時(shí)應(yīng)用可以繼續(xù)處理自己的事情。Gra...
    John_LS閱讀 3,687評(píng)論 3 2
  • 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
  • 程序中同步和異步是什么意思?有什么區(qū)別? 解釋一:異步調(diào)用是通過(guò)使用單獨(dú)的線程執(zhí)行的。原始線程啟動(dòng)異步調(diào)用,異步調(diào)...
    風(fēng)繼續(xù)吹0閱讀 1,110評(píng)論 1 2
  • 每次第二天跑步的時(shí)候都是好累好累,腿都邁不開(kāi),全靠意志力在堅(jiān)持?告訴自己加加油,第一個(gè)兩天已經(jīng)完成?~繼續(xù)努力?。?/div>
    帥氣的火火閱讀 192評(píng)論 0 0

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