天天看點

Dispatch Source

1、它有什麼用

       dispatch source 的作用是負責監聽事件,先看看它的構造函數。

[objc] view plaincopy

Dispatch Source
Dispatch Source
  1. dispatch_source_create(dispatch_source_type_t type,  
  2. uintptr_t handle,  
  3. unsigned long mask,  
  4. dispatch_queue_t queue);  

       第1個參數:要監聽的事件類型

       第2個參數:可以了解為句柄、索引或id,假如要監聽程序,需要傳入程序的ID

       第3個參數:根據參數2,可以了解為描述,提供更詳細的描述,讓它知道具體要監聽什麼

       第4個參數:當事件發生時,将block添加至哪個隊列來執行

2、可監聽事件的類型

       DISPATCH_SOURCE_TYPE_TIMER        定時響應

        DISPATCH_SOURCE_TYPE_SIGNAL      接收到UNIX信号時響應

        DISPATCH_SOURCE_TYPE_READ   IO操作,如對檔案的操作、socket操作的讀響應

        DISPATCH_SOURCE_TYPE_WRITE     IO操作,如對檔案的操作、socket操作的寫響應   

        DISPATCH_SOURCE_TYPE_VNODE    檔案狀态監聽,檔案被删除、移動、重命名

        DISPATCH_SOURCE_TYPE_PROC  程序監聽,如程序的退出、建立一個或更多的子線程、程序收到UNIX信号

        DISPATCH_SOURCE_TYPE_MACH_SEND

        DISPATCH_SOURCE_TYPE_MACH_RECV   上面2個都屬于Mach相關事件響應

        DISPATCH_SOURCE_TYPE_DATA_ADD

        DISPATCH_SOURCE_TYPE_DATA_OR          上面2個都屬于自定義的事件,并且也是有自己來觸發

3、怎麼使用

 (一)自定義事件(DISPATCH_SOURCE_TYPE_DATA_ADD、DISPATCH_SOURCE_TYPE_DATA_OR),先看代碼

Dispatch Source
Dispatch Source
  1. dispatch_source_t source =dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, dispatch_get_main_queue());  
  2. dispatch_source_set_event_handler(source,^{  
  3.        NSLog(@"監聽函數:%lu",dispatch_source_get_data(source));  
  4. });  
  5. dispatch_resume(source);  
  6. dispatch_queue_t myqueue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL);  
  7. dispatch_async(myqueue, ^ {  
  8.       int i;  
  9.       for(i = 0;i<</span>4;i++){  
  10.          dispatch_source_merge_data(source,i);  
  11.       }  

首先使用dispatch_source_create函數建立 dispatchsource,第1個參數表示它是一個自定義的_ADD類型的監聽,具體作用後面說,2、3參數這裡面沒有作用設定為0即可,第4個參數 表示一旦事件觸發就将要執行的代碼塊添加到主隊列中執行,接着我們使用dispatch_source_set_event_handler函數為這個監 聽設定事件的源和響應體,第1個參數表示這個監聽是響應使用者自定義事件的,也就是我們上面定義的dispatchsource,第2個參數是負責響應的代 碼塊。很有意思的是當我們建立監聽後,這個監聽預設是挂起的,需要手動恢複,是以我們使用dispatch_resume函數恢複這個監聽,為了測試這個 監聽,我們後面又通過for循環觸發事件,觸發事件的函數就是dispatch_source_merge_data,這個函數負責觸發自定義事件,第1 個參數表示要觸發哪個監聽,第2個參數是向監聽傳入一個unsigned long 類型的值, 我們這裡傳入循環的索引,好了,整體來看這段程式,dispatch_source_merge_data函數會被執行4次,并分别傳入0、1、2、3這 4個值,既然dispatch_source_merge_data負責觸發事件,那麼我們在監聽裡面的響應體應該會監聽到,結果也确實監聽到了,但是并 不是我們想象的那樣列印4次,而是隻列印了一次,列印結果是4次傳入值相加的和,也就是6,這就是 DISPATCH_SOURCE_TYPE_DATA_ADD參數的作用,這個監聽在建立之初就被設定為自定義監聽,并且會把監聽結果相加,然後統一響 應。這裡你應該會奇怪,既然結果會相加并統一響應,那跟觸發的時候加好,然後觸發一次有什麼差別呢,好吧,我們把觸發事件的for循環改一下,然後再運 行,看看會發生什麼

Dispatch Source
Dispatch Source
  1. for(i = 0;i<</span>4;i++){  
  2.     dispatch_source_merge_data(source,i);  
  3.     [NSThread sleepForTimeInterval:0.0001];  
  4. }