GCD知識

Grand Central Dispatch =GDC

1.有兩種:順序的serial Dispatch Queue 與 併發的Concurrent Dispatch Queue
     前者是全部加入這個queue的block會順序執行,完成一個在開始第二個。既此隊列只開一個線程順序執行。
     後者是全部加入這個queue的block會併發執行,第二個的開始與第一個是否結束無關,他會選擇最有解決線程建立方案,不會每一個block建立一個線程(好比b1,b2,b3當要執行b3的時候,b1執行完了,此時b3會加入b1的線程而不會從新建立)。

2.建立方式
     dispatch_queue_t xxx = dispatch_queue_create("queueName",Null) //這個是建立了serial Dispatch Queue
     dispatch_queue_t xxx = dispatch_queue_create("queueName",DISPATCH_QUEUE_CONCURRENT);//這個是建立concurrent dispatch queue
須要人工release

3.Main Dispatch Queue/Global Dispatch Queue
   Main Dispatch Queue 主線程隊列 加入此線程的都會在主線程進行執行,既丟入NSRunLoop裏。通常須要刷新頁面相關的纔會使用。
   Global Dispatch Queue 是作一個快速獲取的Concurrent dispatch queue存在的,他有4個優先級 background,low,default,high
注意:使用MainDQ 和 GlobalDQ 是不須要進行retain 或release的 

4.dispatch_set_target_queue
     設置隊列優先級。
dispatch_set_target_queue(Q1,Q2);
Q1爲須要修改優先級的,Q2爲Q1要與他同級的。
MainDQ 與GlobalDQ由於是全局 因此沒法做爲第一個參數。
     在必須將不可並行的處理追加到多個serial Dispatch Queue 中時,若是使用dispatch_set_target_queue函數將目標指定爲某一個serialDispatchQueue便可防止處理並行執行。

5.dispatch_after 與 dispatch_walltime
     dispatch_after 爲延遲多久加入隊列(相對時間)
     dispatch_walltime 爲在什麼時間加入隊列(絕對時間)
ex:
     dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW,3ull * NSEC_PER_SEC);
     dispatch_after(time,dispatch_get_main_queue(),^{…});
     dispatch_time_t 是從第一個參數的時間開始,經歷第二個參數的時長以後。
     ull 是C語言數值字面量
     NSEC_PER_SEC爲秒爲計數單位
     NSEC_PER_MSEC爲毫秒的計數單位
     dispatch_walltime 返回的爲dispatch_time_t

*6.Disptach Group
將dispatch 加入group,而且設置執行group隊列完後的執行代碼。
     ex:
     dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_DEFAULT,0);
dispatch_group_t group=disptach_group_create();
dispatch_group_async(group,queue,^{1...});
dispatch_group_async(group,queue,^{2...});
dispatch_group_async(group,queue,^{3...});
dispatch_group_notify(group,dispatch_get_main_queue(),^{結束後執行的});
dispatch_release(group);

注意:在dispatch_group_notify函數中無論指定怎麼樣的Dispatch Queue,屬於Dispatch Group的處理在追加的block(上面例子的【結束後執行的】)時都已經結束。

另外還有dispatch_group_wait(group,DISPATCH_TIME_FOREVER);
這個表示 調用他的線程永遠等待(由於第二個參數DISPATCH_TIME_FOREVER,若是是其餘ex:disptach_time_t time=dispatch_time(DISPATCH_TIME_NOW,1ull*NSEC_PER_SEC);
dispatch_group_wait(group,time);
的話就是等待1秒) 
long result=dispatch_group_wait(……);
返回值爲long型
if(result==0){
    // 等待時間結束後,group的所有處理執行結束
}else{
    // 等待時間結束後,group的還有未完成的處理
}

正常狀況下不使用dispatch_group_wait,而使用dispatch_group_notify(group,dispatch_get_main_queue(),^{結束後執行的});
能夠更好的簡化代碼。

7.dispatch_barrier_async
     爲了規避Concurrent dispatch queue使用中的併發讀取數據,數據競爭等問題。
使用dispatch_barrier_async
ex:
     queue 爲Concurrent dispatch queue
     queue 其餘處理1
     queue 其餘處理2
     dispatch_barrier_async(queue,blk_for_writing)
     queue 其餘處理3
     queue 其餘處理4
     其餘處理1 2 執行完 纔會執行dispatch_barrier_async,dispatch_barrier_async執行完纔會執行 其餘處理 3 4
     若是其餘處理都是數據庫讀操做  dispatch_barrier_async是數據庫寫操做,那麼這樣能保證 3 4 讀取的數據是修改(寫入)後的,數據保持正確。

8.dispatch_sync
     同步執行,與dispatch_async相反。此方法不能將block加到,mainQueue中,會致使死鎖。也不能給Serial Dispatch Queue增長block,也會致使死鎖。
     簡單的說這個通常不用,用只用在Concurrent dispatch queue中。(其實通常不會用到)

9.dispatch_apply
     重複執行block,x次。
ex:     dispatch(10,queue,^{…block…});
          NSlog(@「done");
     重複執行block 10次,而且等待執行結束後才繼續執行NSlog(@「done」)。
注意:dispatch_apply([array count],queue,^(size_t index){…block…});
     size_t index表明數組下標,上面代碼會將數組array的每一個下表都丟入block中執行一次。

10.dispatch_suspend/dispatch_resume
    dispatch_suspend 掛起已經追加的處理(未執行的處理暫不執行)
    dispatch_resume 恢復已經追加的處理

11.Dispatch Semaphore 
     代碼性排他,經過計數器來限制當前代碼在執行過程當中只能有限的線程數執行。
建立:dispatch_semaphore_t semaphore=dispatch_semaphore_create(1);
建立一個dispatch_semaphore_t 而且初始化計數爲1;

等待(此代碼後開始限制線程(排他),加鎖,而且計數-1)。
dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);

排他控制結束(解鎖,而且計數+1)
disptach_semaphore_signal(semaphore);

12.Dispatch_once
     保證在應用程序執行過程當中只執行一次的指令。
     static dispatch_once_t pred;s
dispatch_once(&pred, ^{……});

13.Dispatch I/O
     經過使用Dispatch I/O能夠併發讀寫數據,提升效率

14.dispatch_queue 與 dispatch_source
     dispatch_queue是沒法中斷的,要麼使用內部標誌位。
     而dispatch_source 而且能夠設置回調的cancel block。數據庫

相關文章
相關標籤/搜索