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。數據庫