GCD的一些使用總結

GCD group多任務分組

經常遇到多個請求嵌套或者是一個頁面同時發起請求的情況,遇到這個情況,解決方法多種多樣:
  • 不用多線程最簡單粗暴的方式是前一個請求成功回調之后接著下一個請求 (優點: 很簡單,不需要思考 缺點: 這樣循環嵌套,地獄式回調,副作用多多,耦合依賴太嚴重了...)
  • GCD串行隊列,但是請求是異步返回的,所以這個方案不是那么可靠 (?)
  • dispatch_barrier_async這個是等待前面任務執行完,才開始下面的操作,這個也是可以的
  • GCD group 一開始使用的不是全局隊列(自己創建的串行隊列),結果group返回順序是亂的,于是我采用了全局變量將返回結果存起來,到dispatch_group_notify的時候進行賦值操作... 這樣顯得累贅 (以上都是同理可得,先返回又怎樣,存起來,等待一個公共的刷新時機,總覺得有點趕,有點倉促的趕腳,一起懟會不會短時間內耗費大量的性能什么的,后來看了下FPS,果然進入頁面的瞬間FPS相當的低,不過刷新頁面之后都是保持在60左右)
  • 后來才發現,group要和全局隊列(dispatch_queue_t globalQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)和系統的全局主隊列dispatch_queue_t mainQ = dispatch_get_main_queue()這些都屬于串行隊列的范疇) 一起食用,效果更佳.
dispatch_group_enter(group)和dispatch_group_leave(group)的使用
dispatch_group_enter(group); ///開始請求前`
dispatch_group_async(group, queue, ^{
     ///請求
 });
dispatch_group_leave(group);///請求成功或者失敗返回 請求結束的時候
這兩者要配套使用,效果才更顯著 ,類似于信號量或者引用計數之類的玩意兒
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
         ///insert callBack reloadData  operation code
});

dispatch_barrier_async 柵欄什么鬼的

*我之前理解的是一個小河流,遇到一塊大石頭堵住了,然后從旁邊或者溢滿過去,然而并不形象... 就像一個收保護費的,不對! 或者是一個堤壩的過濾河道垃圾的一個玩意,也不準確! 其實更像是一個收費站,來往有很多的車輛,有的車開的很快跑到前面,有的車開的比較慢落在后面,無論快與慢,都得經過收費站這個坎... *

這個dispatch_barrier_async 起了一個攔截的作用,就是不管你們前面誰先到我這里,你都得帶通行證(可以理解為了完成任務)才讓通行,才能執行下面的任務.

dispatch_after

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            ///延時3秒操作~
    });

dispatch_once

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
            ///只執行一次
    });

dispatch_apply

  • 執行某個代碼片段N次。
dispatch_apply(5, globalQ, ^(size_t index) {
    // 執行5次
});

隊列

全局隊列優先級

#define DISPATCH_QUEUE_PRIORITY_HIGH 2   //高
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 //默認
#define DISPATCH_QUEUE_PRIORITY_LOW (-2) //低
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN //后臺
//main_queue 主隊列 串行
dispatch_queue_t mainQueue = dispatch_get_main_queue();

//global_queue 全局隊列 并行
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//custom_queue 自定義隊列 串行
dispatch_queue_t customQueue = dispatch_queue_create("com.wgb.gcd", nil);

并行,串行,同步,異步

  • 并行隊列+異步: 創建子線程,且多個子線程,異步任務返回結果先后順序是無序的
  • 并行+同步: 不創建子線程,同步任務一個個有序執行,不存在并發
  • 串行+異步: 先主線程-> 子線程(會開啟線程)一個個有序執行異步的操作
  • 串行+同步: 不創建子線程,同步任務執行是有序的,然后都在主線程里執行,會阻塞當前線程導致UI卡死等癥狀
總結: 同步不開啟子線程,任務一個個有序執行,異步開啟子線程;串行只開啟一個子線程,并行開啟多個線程。
參考:

GCD使用三部曲之:基本用法
GCD編程中串行、并行、同步、異步的執行順序
iOS多線程--徹底學會多線程之『GCD』

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

推薦閱讀更多精彩內容