一.GCD基礎(chǔ)概念:{
1 .概念:Grand Central Dispatch,純C語(yǔ)言的,提供了很多非常強(qiáng)大的函數(shù);
2 .GCD優(yōu)勢(shì):{
a.GCD為多核運(yùn)算的并行運(yùn)算提供解決方案;
b.GCD會(huì)自動(dòng)利用更多的CPU內(nèi)核(如2核/4核);
c.GCD會(huì)自動(dòng)管理線程的生命周期(創(chuàng)建/調(diào)度/銷毀);
d.只需告訴GCD做什么任務(wù),不用編寫管理代碼;}
3 .GCD的核心:'將任務(wù)添加到隊(duì)列'{
a. 任務(wù):執(zhí)行什么操作;
b. 隊(duì)列:用來(lái)存放任務(wù);}
4 .GCD的使用的兩個(gè)步驟:{
a .創(chuàng)建任務(wù):確定要做的事情,用Block封裝任務(wù);
b .將任務(wù)添加到隊(duì)列中:{
GCD"自動(dòng)"從隊(duì)列中將任務(wù)取出,放到對(duì)應(yīng)的線程中執(zhí)行.
任務(wù)的去除遵循隊(duì)列的"FIFO"原則:'先進(jìn)先出,后進(jìn)后出'
}}}
二.隊(duì)列和任務(wù):{
(一).隊(duì)列:{
1. 串行隊(duì)列:'DISPATCH_QUEUE_SERIAL'{
- 定義:
dispatch_queue_t queue = dispatch_queue_create("隊(duì)列標(biāo)識(shí)符", DISPATCH_QUEUE_SERIAL);
- 串行對(duì)類讓任務(wù)"一個(gè)一個(gè)有序"的執(zhí)行,一個(gè)執(zhí)行完后,再執(zhí)行下一個(gè)
- 同時(shí)只能調(diào)度一個(gè)任務(wù)執(zhí)行;}
2. 并發(fā)隊(duì)列:'DISPATCH_QUEUE_CONCURRENT'{
- 定義:
dispatch_queue_t queue = dispatch_queue_create("隊(duì)列標(biāo)識(shí)符", DISPATCH_QUEUE_CONCURRENT);
- 可以讓多任務(wù)"同時(shí)(并發(fā))"執(zhí)行,自動(dòng)開啟多個(gè)線程同時(shí)執(zhí)行多個(gè)任務(wù);
- 并發(fā)隊(duì)列的并發(fā)功能只有內(nèi)部的任務(wù)是"異步任務(wù)"的時(shí)候,才有效}}
(二).任務(wù):{
1. 同步執(zhí)行任務(wù):在'當(dāng)前線程'中'依次'執(zhí)行任務(wù){(diào)
dispatch_sync(dispatch_queue_t queue,dispatch_block_t block)
- queue:隊(duì)列
- block:任務(wù)}
2. 異步執(zhí)行任務(wù):'新開線程',在新線程中執(zhí)行任務(wù){(diào)
dispatch_async(dispatch_queue_t queue.dispatch_block_t block);
- queue:隊(duì)列
- block:任務(wù)}}}
三.延時(shí)操作:延遲多少納秒,在哪個(gè)隊(duì)列中調(diào)度執(zhí)行哪個(gè)任務(wù){(diào)
- 函數(shù):dispatch_after(dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block)
- 參數(shù):{
a.dispatch_time_t 'when':延遲的時(shí)間;
b.dispatch_queue_t 'queue':執(zhí)行任務(wù)的隊(duì)列;
c.dispatch_block_t 'block':線程要執(zhí)行的任務(wù);}}
四.隊(duì)列和任務(wù)組合{
- 串行隊(duì)列 + 同步任務(wù):{
a. "沒(méi)有"開新線程,在當(dāng)前線程中執(zhí)行;
b. 線程內(nèi)任務(wù)"順序"執(zhí)行;
c. "執(zhí)行完"線程中所有任務(wù)后,執(zhí)行線程中其他任務(wù);} - 串行隊(duì)列 + 異步任務(wù):{
a. "新開"一條線程,原因看下一條;
b. 新線程中前一個(gè)任務(wù)執(zhí)行完后執(zhí)行后一個(gè)任務(wù);
c. 原來(lái)線程中的任務(wù)異步執(zhí) ,"不必"等待新任務(wù)執(zhí)行完;} - 并發(fā)隊(duì)列 + 同步任務(wù):{
a. "沒(méi)有"開新線程,在當(dāng)前線程中執(zhí)行;
b. 線程內(nèi)任務(wù)"順序"執(zhí)行;
c. "執(zhí)行完"線程中所有任務(wù)后,執(zhí)行線程中其他任務(wù);} - 并發(fā)隊(duì)列 + 異步任務(wù):{
a. 開啟"多條"新線程;
b. 線程內(nèi)任務(wù)"隨機(jī)"執(zhí)行;
c. 線程外任務(wù)"異步"執(zhí)行;} - 總結(jié):{
- 先看任務(wù):如果是同步任務(wù)迹鹅,則不開新線程,任務(wù)依次執(zhí)行斜棚,線程內(nèi)任務(wù)執(zhí)行完后執(zhí)行線程外任務(wù);
- 如果是異步任務(wù)蜗字,看隊(duì)列:串行隊(duì)列新建一個(gè)線程脂新,新線程內(nèi)任務(wù)依次執(zhí)行,原線程中任務(wù)無(wú)需等待争便;
- 如果是并發(fā)隊(duì)列级零,開啟多條線程滞乙,新線程內(nèi)任務(wù)隨機(jī)執(zhí)行,原線程內(nèi)任務(wù)無(wú)需等待斩启,在原線程中執(zhí)行
}}
五.主隊(duì)列:dispatch_get_main_queue(){
1.特點(diǎn):{
a. 專門用來(lái)在主線程上調(diào)度任務(wù)的隊(duì)列;
b. 不會(huì)開啟新線程;
c. 以先進(jìn)先出的方式,在主線程空閑的時(shí)候才會(huì)調(diào)度隊(duì)列中的任務(wù)在主線程中執(zhí)行;
d. 如果當(dāng)前主線程有正在執(zhí)行的任務(wù),那么無(wú)論主隊(duì)列中當(dāng)前被添加了什么任務(wù),都不會(huì)被調(diào)度
e. 主隊(duì)會(huì)隨著主程序啟動(dòng)一起創(chuàng)建,只需獲取,不用創(chuàng)建;
}
2.組合:{
a. 主隊(duì)列 + 異步隊(duì)列:先執(zhí)行隊(duì)列外的主線程中的任務(wù),待主線程中任務(wù)都執(zhí)行完了以后再執(zhí)行隊(duì)列中的任務(wù);
任務(wù)1 -> dispatch_async{dispatch_get_main_queue(),^ (任務(wù)2)} ->任務(wù)3
執(zhí)行順序:任務(wù)1 -> 任務(wù)3 -> 任務(wù)2;
b. 主隊(duì)列 + 同步任務(wù) = 鎖死:
原因分析:主線程在等待同步任務(wù)執(zhí)行完,同步任務(wù)中的主隊(duì)列在等待主線程中的任務(wù)執(zhí)行完畢;
解決辦法:將主隊(duì)列的同步任務(wù)放到子線程中(這么作,何必呢?);}}
六.全局隊(duì)列:dispatch_get_global_queue(0, 0){
- 定義:全局并發(fā)隊(duì)列,系統(tǒng)提供的,工作表現(xiàn)和并發(fā)隊(duì)列一致;
- 全局隊(duì)列:并發(fā)隊(duì)列{'比較'
a. 沒(méi)有名字:有名字
b. 無(wú)論ARC還是MRC都不需要考慮釋放:MRC下需要dispatch_release(q)
c. "日常開發(fā)"中推薦使用:"開發(fā)第三方框架"建議使用并發(fā)}}
七.GCD應(yīng)用:{
建立依賴:同步任務(wù){(diào)
//獲取全局隊(duì)列
dispatch_queue_t queue = dispatch_get_global_queue(0,0);
//在全局隊(duì)列中執(zhí)行異步任務(wù),防止耗時(shí)任務(wù)在主線程中執(zhí)行
dispatch_async(queue, ^{
//建立'任務(wù)1','任務(wù)2','任務(wù)3'的依賴關(guān)系,1,2,3依次完成
dispatch_sync(queue, ^{任務(wù)1});
dispatch_sync(queue, ^{任務(wù)2});
...
dispatch_sync(queue, ^{任務(wù)3});
//回到主線程刷新UI(使用異步任務(wù),防止卡頓)
dispatch_async(dispatch_get_main_queue, ^{主線程刷新UI})
})
}-
一次性執(zhí)行:dispatch_once_t{
內(nèi)部有一把鎖,保證內(nèi)部代碼只執(zhí)行一次:
a. 'once用于設(shè)計(jì)單例模式:'{
static NetworkTool *instance;
//敲dispatch_once會(huì)有提示
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[NetworkTool alloc] init];
});return instance;
}
b. '互斥鎖單例設(shè)計(jì)模式:'{
static AccountManager *manager;// 為保證在多線程的環(huán)境下,線程的安全,所以添加了一把互斥鎖
// 但是互斥鎖的性能有點(diǎn)兒差
@synchronized(self) {
// 判斷內(nèi)存中有沒(méi)有這個(gè)對(duì)象,如果沒(méi)有,就創(chuàng)建
if (manager == nil) {
manager = [[AccountManager alloc] init];
}
}
return manager;}
c. 比較:性能once更好,操作更簡(jiǎn)單;} 調(diào)度組
}