iOS 使用dispatch_group_enter使多次網絡請求依次執行

常用的幾個方法

  • dispatch_group_enter :通知 group,下個任務要放入 group 中執行了
  • dispatch_group_leave: 通知 group,任務成功完成,要移除,與 enter成對出現
  • dispatch_group_wait: 在任務組完成時調用,或者任務組超時是調用(完成指的是enter和leave次數一樣多)
  • dispatch_group_notify: 只要任務全部完成了,就會在最后調用

具體情況分析

詳見:dispatch_group_enter 使用與講解

實際應用

我們就可以使用dispatch_group_enter了,在執行了多段之后再在 notify 中執行另一個,類似于柵欄的效果.但是如果是網絡請求,需要達到網絡請求嵌套的效果,A網絡請求完之后再請求 B,需要添加dispatch_group_wait,讓線程等待 A 執行完成之后再執行 B.

// A 請求數據
- (void)loadADataFinished:(void(^)(BOOL success))finished;
// B 請求數據
- (void)loadBDataFinished:(void(^)(BOOL success))finished;
// C 請求數據
- (void)loadCDataFinished:(void(^)(BOOL success))finished;

// 請求是否全部完成
- (void)finishedDataFinished:(void(^)(BOOL success))finished{
  dispatch_group_t group = dispatch_group_create(); 
  dispatch_group_enter(group);
  [self loadADataFinished:^(BOOL success){
    if (success){
      dispatch_group_leave(group);
    }else{
      finished(NO);
    }
  }];
  dispatch_group_enter(group);
  [self loadBDataFinished:^(BOOL success){
    if (success){
      dispatch_group_leave(group);
    }else{
      finished(NO);
    }
  }]; 

 dispatch_group_wait(group, DISPATCH_TIME_FOREVER);// A,B同時執行, 執行完才會執行下面的 C
 dispatch_group_enter(group);
 [self loadCDataFinished:^(BOOL success){
    if (success){
      dispatch_group_leave(group);
    }else{
      finished(NO);
    }
  }]; 
 
  //  group 中的任務都成功完成后,才會返回 YES
  dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        finished(YES);
   });
}

在我們的項目中,在一個 VC 中會有多個網絡請求A,B.現在要實現的是:A 請求數據成功之后,再執行 B 的網絡請求.這時候因為網絡請求是異步的,所以我們要達到效果,需要在子線程中加入信號量dispatch_semaphore_t,在網絡請求內部標記信號量,請求完成之后將信號量清為 0.

// A 請求數據
- (void)loadADataFinished:(void(^)(BOOL success))finished;
// B 請求數據
- (void)loadBDataFinished:(void(^)(BOOL success))finished;

dispatch_async(dispatch_get_global_queue(0, 0), ^{

        dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
         [self loadADataFinished:^(BOOL success){
            if (success){ 
              }else{
                 finished(NO);
             }
              dispatch_semaphore_signal(semaphore);
         }]; 
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); // A請求完成之后,請求 B
         [self loadBDataFinished:^(BOOL success){
            if (success){ 
              }else{
                 finished(NO);
             }
              dispatch_semaphore_signal(semaphore);
         }];  
});

其他情況可以參考:GCD 的控制使用

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

推薦閱讀更多精彩內容

  • 博客鏈接深入理解GCD之dispatch_group 之前已經介紹了dispatch_semaphore的底層實現...
    NeroXie閱讀 30,972評論 11 86
  • 一、簡單介紹下將會用到的一些東西 英語不好就不翻譯官方文檔了.. 1、dispatch_group_async S...
    Albert新榮閱讀 1,751評論 0 1
  • 一:base.h 二:block.h 1. dispatch_block_flags:DISPATCH_BLOCK...
    小暖風閱讀 2,478評論 0 0
  • 偶然間,看過這樣四幅畫,第一幅圖是一個玻璃瓶子,第二幅圖剛剛發育的樹苗,第三幅圖是茁壯成長的小樹,第四幅圖...
    哆啦A藍夢閱讀 573評論 2 1
  • 南京作為古中國的十朝古都,如今又是江蘇省的省會城市,本次有幸參觀此城,望不會令人失望! 2018蘇南杭之行1 - ...
    愛折騰的公子哥閱讀 316評論 0 3