GCD -- 簡單的總結(jié)!

本文不說什么是GCD,只將其簡單的總結(jié),有利于在項(xiàng)目中的使用!

1.在GCD中,個(gè)人不需要關(guān)心線程的開辟!

2.任務(wù)有同步任務(wù)(同步執(zhí)行)和異步任務(wù)(異步執(zhí)行),他們之間的區(qū)別是是否會(huì)創(chuàng)建新的線程

3.如果是同步(sync)操作,它會(huì)阻塞當(dāng)前線程并等待Block中的任務(wù)執(zhí)行完畢,然后當(dāng)前線程才會(huì)繼續(xù)往下運(yùn)行。
如果是異步(async)操作,當(dāng)前線程會(huì)直接往下執(zhí)行,它不會(huì)阻塞當(dāng)前線程。

4.隊(duì)列:用于存放任務(wù)。一共有兩種隊(duì)列, 串行隊(duì)列并行隊(duì)列。
放到串行隊(duì)列的任務(wù),GCD 會(huì)FIFO(先進(jìn)先出)地取出來一個(gè),執(zhí)行一個(gè),然后取下一個(gè),這樣一個(gè)一個(gè)的執(zhí)行;
放到并行隊(duì)列的任務(wù),GCD 也會(huì)FIFO
的取出來,但不同的是,它取出來一個(gè)就會(huì)放到別的線程,然后再取出來一個(gè)又放到另一個(gè)的線程。這樣由于取的動(dòng)作很快,忽略不計(jì),看起來,所有的任務(wù)都是一起執(zhí)行的。不過需要注意,GCD 會(huì)根據(jù)系統(tǒng)資源控制并行的數(shù)量,所以如果任務(wù)很多,它并不會(huì)讓所有任務(wù)同時(shí)執(zhí)行。

5.我們用圖表來總結(jié)上述的關(guān)系

同步任務(wù) 異步任務(wù)
串行隊(duì)列 當(dāng)前線程,一個(gè)一個(gè)執(zhí)行 其他線程,一個(gè)一個(gè)執(zhí)行
并行隊(duì)列 當(dāng)前線程,一個(gè)一個(gè)執(zhí)行 開很多線程,一起執(zhí)行

6.自己可以創(chuàng)建串行隊(duì)列, 也可以創(chuàng)建并行隊(duì)列。我們先來看看一個(gè)GCD代碼

dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT)

其中第二個(gè)參數(shù)是最重要的。第二個(gè)參數(shù)用來表示創(chuàng)建的隊(duì)列是串行的還是并行的:
傳入DISPATCH_QUEUE_SERIAL
或NULL表示創(chuàng)建串行隊(duì)列。
傳入DISPATCH_QUEUE_CONCURRENT
表示創(chuàng)建并行隊(duì)列,其中并行隊(duì)列有系統(tǒng)定義的四種優(yōu)先級 ,比如DISPATCH_QUEUE_PRIORITY_DEFAULT’

獲取主隊(duì)列方法

// 獲取主隊(duì)列
dispatch_queue_t mainQueue = dispatch_get_main_queue();

兩者綜合:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{    
  [NSThread sleepForTimeInterval:2];        
  dispatch_async(dispatch_get_main_queue(), ^{    
         //主線程更新UI
   }) ;    
  });

這是一段我們都非常熟悉的代碼,其中包含著

dispatch_async 是異步任務(wù)
dispatch_get_global_queue 全局隊(duì)列
dispatch_get_main_queue 主隊(duì)列
DISPATCH_QUEUE_PRIORITY_DEFAULT 創(chuàng)建并行隊(duì)列


例子1:


dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT);   
 NSLog(@“并行隊(duì)列上放同步任務(wù)");   
 dispatch_sync(concurrentQueue, ^(){  
      NSLog(@"sync - 同步任務(wù)");   
     [NSThread sleepForTimeInterval:5];   
     NSLog(@“sync5秒后");  
  });  
 NSLog(@“結(jié)束");

輸出 :

GCDTest[] 并行隊(duì)列上放同步任務(wù)

GCDTest[] sync - 同步任務(wù)

GCDTest[] ** sync5秒后**//模擬長時(shí)間操作

GCDTest[] 結(jié)束

可以見得,同步任務(wù)要做完Block中的任務(wù),才能繼續(xù)往下執(zhí)行

最常見的使用就是FMDB 中的[queue inDatabase:^(FMDatabase *db)


例子二:


dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT);
   NSLog(@"并行隊(duì)列上放同步任務(wù)");
   dispatch_async(concurrentQueue, ^(){
       NSLog(@"async");
       [NSThread sleepForTimeInterval:5];
       NSLog(@“async5秒后");
   });
NSLog(@“結(jié)束”);

輸出:

GCDTest[] 并行隊(duì)列上放同步任務(wù)

GCDTest[] 結(jié)束

GCDTest[] async

GCDTest[]** async5秒后**//模擬長時(shí)間操作時(shí)間

可以見得,異步任務(wù)不用做完Block中的任務(wù),已經(jīng)開始繼續(xù)往下執(zhí)行

10 barrier

func dispatch_barrier_async(_ queue: dispatch_queue_t, _ block: dispatch_block_t)

:這個(gè)方法重點(diǎn)是你傳入的 queue,當(dāng)你傳入的 queue 是通過DISPATCH_QUEUE_CONCURRENT
參數(shù)自己創(chuàng)建的 queue 時(shí),這個(gè)方法會(huì)阻塞這個(gè) queue注意是阻塞 queue ,而不是阻塞當(dāng)前線程),一直等到這個(gè) queue 中排在它前面的任務(wù)都執(zhí)行完成后才會(huì)開始執(zhí)行自己,自己執(zhí)行完畢后,再會(huì)取消阻塞,使這個(gè) queue 中排在它后面的任務(wù)繼續(xù)執(zhí)行。如果你傳入的是其他的 queue, 那么它就和dispatch_async
一樣了。

func dispatch_barrier_sync(_ queue: dispatch_queue_t, _ block: dispatch_block_t)

:這個(gè)方法的使用和上一個(gè)一樣,傳入 自定義的并發(fā)隊(duì)列(DISPATCH_QUEUE_CONCURRENT),它和上一個(gè)方法一樣的阻塞 queue,不同的是 這個(gè)方法還會(huì) 阻塞當(dāng)前線程。
如果你傳入的是其他的 queue, 那么它就和dispatch_sync
一樣了。

有另外一種介紹:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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