GCD -- 簡單的總結!

本文不說什么是GCD,只將其簡單的總結,有利于在項目中的使用!

1.在GCD中,個人不需要關心線程的開辟!

2.任務有同步任務(同步執行)和異步任務(異步執行),他們之間的區別是是否會創建新的線程

3.如果是同步(sync)操作,它會阻塞當前線程并等待Block中的任務執行完畢,然后當前線程才會繼續往下運行。
如果是異步(async)操作,當前線程會直接往下執行,它不會阻塞當前線程。

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

5.我們用圖表來總結上述的關系

同步任務 異步任務
串行隊列 當前線程,一個一個執行 其他線程,一個一個執行
并行隊列 當前線程,一個一個執行 開很多線程,一起執行

6.自己可以創建串行隊列, 也可以創建并行隊列。我們先來看看一個GCD代碼

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

其中第二個參數是最重要的。第二個參數用來表示創建的隊列是串行的還是并行的:
傳入DISPATCH_QUEUE_SERIAL
或NULL表示創建串行隊列。
傳入DISPATCH_QUEUE_CONCURRENT
表示創建并行隊列,其中并行隊列有系統定義的四種優先級 ,比如DISPATCH_QUEUE_PRIORITY_DEFAULT’

獲取主隊列方法

// 獲取主隊列
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 是異步任務
dispatch_get_global_queue 全局隊列
dispatch_get_main_queue 主隊列
DISPATCH_QUEUE_PRIORITY_DEFAULT 創建并行隊列


例子1:


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

輸出 :

GCDTest[] 并行隊列上放同步任務

GCDTest[] sync - 同步任務

GCDTest[] ** sync5秒后**//模擬長時間操作

GCDTest[] 結束

可以見得,同步任務要做完Block中的任務,才能繼續往下執行

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


例子二:


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

輸出:

GCDTest[] 并行隊列上放同步任務

GCDTest[] 結束

GCDTest[] async

GCDTest[]** async5秒后**//模擬長時間操作時間

可以見得,異步任務不用做完Block中的任務,已經開始繼續往下執行

10 barrier

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

:這個方法重點是你傳入的 queue,當你傳入的 queue 是通過DISPATCH_QUEUE_CONCURRENT
參數自己創建的 queue 時,這個方法會阻塞這個 queue注意是阻塞 queue ,而不是阻塞當前線程),一直等到這個 queue 中排在它前面的任務都執行完成后才會開始執行自己,自己執行完畢后,再會取消阻塞,使這個 queue 中排在它后面的任務繼續執行。如果你傳入的是其他的 queue, 那么它就和dispatch_async
一樣了。

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

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

有另外一種介紹:

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容