0

我需要在調用api(NS​​URLSessionDataTask async)的單獨線程中相繼運行3個方法。我特地到調度組,但是這似乎在同一時間運行方法1和2,然後運行方法3,當他們完成:依次運行3個方法

dispatch_group_t group = dispatch_group_create(); 

//METHOD 1 
dispatch_group_enter(group); 
[self method1WithCompletion:^(BOOL success){ 
    dispatch_group_leave(group); 
}]; 

//METHOD 2 
dispatch_group_enter(group); 
[self method2WithCompletion:^(BOOL success){ 
    dispatch_group_leave(group); 
}]; 

dispatch_group_notify(group,dispatch_get_main_queue(),^{ 
    //METHOD 3 
}); 

我需要它來運行方法1和完成時運行的方法2,當完成時最後運行方法3(排隊方法)。

我知道我可以鏈接每個完成的方法來運行下一個,但我認爲會有更好的方法來...這有什麼想法?

+1

調用[self method1]有什麼問題; [self method2]; [self method3]; ? – 2015-02-10 12:50:49

+0

@RicardPérezdelCampo這樣做會導致所有3個異步任務立即發生。他想在方法1完成後調用方法2,方法2完成後調用方法3。 – cjwirth 2015-02-10 12:54:30

+0

所以這不會工作?[self method1WithCompletion:^(BOOL success){ }];自我方法1完成:^(BOOL成功){自我方法2完成:^(BOOL成功) }]; }]; – 2015-02-10 12:57:26

回答

0

你就近了。

dispatch_group_enter和公司只處理該位,所以在調用傳遞到dispatch_group_notify的塊之前,dispatch_group_enterdispatch_group_t的所有內容都將完成。

所以我們可以在等待任務時使用它們。而不是僅僅1組等待每一個任務來完成,我們可以用一組針對需要完成每個異步任務:

// You can get a global queue or create your own, it doesn't really matter 
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
// Create a group for each task you want to wait for 
dispatch_group_t group1 = dispatch_group_create(); 
dispatch_group_t group2 = dispatch_group_create(); 

// Call your first task on the first group 
dispatch_group_enter(group1); 
[self method1WithCompletion:^(BOOL success){ 
    // Task is completed, so signal that it has finished 
    dispatch_group_leave(group1); 
}]; 

// Call your 2nd task on the 2nd group 
dispatch_group_enter(group2); 
// Make the second task wait until group1 has completed before running 
dispatch_group_notify(group1, queue, ^{ 
    // METHOD 2 
    [self method2WithCompletion:^(BOOL success){ 
     // Signal to the group that the task has completed 
     dispatch_group_leave(group2); 
    }]; 
}); 

// Nothing is waiting on the 3rd task, so no need to create a group for it 
dispatch_group_notify(group2,dispatch_get_main_queue(),^{ 
    //METHOD 3 
    // Do whatever you need to do in here 
}); 

下面是一些你可以約Dispatch Queues,以及如何使用它們的更多信息。

編輯:對不起,我完全改變了我的答案。一旦你離開你的評論,它打擊我,你打電話的任務是異步的,並使用串行dispatch_queue_t不會有所作爲! (該塊是串行運行,但方法2將立即方法1後運行,而不是等待完成)

+0

感謝cjwirth,所以在我的method1WithCompletion調用這將仍然工作與串行隊列或將它需要調整太: 'NSURLSessionDataTask *任務= [會議dataTaskWithRequest:請求completionHandler:^(NSData *數據,NSURLResponse *響應,NSError * error){ ** dispatch_async(dispatch_get_main_queue(),^ {** // Handle data etc }); });' – 2015-02-10 12:05:14

+0

請檢查:我的第一個答案是錯誤的......它不應該在你的'method1WithCompletion:'或'method2WithCompletion:'裏面有什麼。方法2將在調用方法1內的完成塊時被調用,並且當方法2內的完成塊被調用時將調用方法3。 – cjwirth 2015-02-10 12:51:57

+0

好的,謝謝你的更新答案。我會告訴你一切,並讓你知道 – 2015-02-10 13:47:35

0

編輯:我不這麼認爲了,cjwirth已經在評論

駁斥我下面的假設

我認爲仍然可以通過serial queue(但它只是假設,我沒有檢查它)。主要想法是將組任務分派到串行隊列中,在派發前使用dispatch_group_enter(group),在您的方法1..2中使用dispatch_group_leave(group)完成。讓我告訴它應該是:

dispatch_queue_t queue = dispatch_queue_create("com.example.MyQueue", NULL); 
dispatch_group_t group = dispatch_group_create(); 

//METHOD 1 
dispatch_group_enter(group); 
dispatch_group_async(group, queue, ^{ 
    [self method1WithCompletion:^(BOOL success){ 
    dispatch_async(queue, ^{      
        dispatch_group_leave(group); 
      }); 
    }]; 
}); 

//METHOD 2 
dispatch_group_enter(group); 
dispatch_group_async(group, queue, ^{ 
    [self method2WithCompletion:^(BOOL success){ 
    dispatch_async(queue, ^{      
        dispatch_group_leave(group); 
      }); 
    }]; 
}); 

dispatch_group_notify(group,dispatch_get_main_queue(),^{ 
    //METHOD 3 
}); 

注:這種實現的樣子有些不對勁。因爲我們已經有了NSOperationQueue,所以我建議你把你的NSURLSessionDataTask的東西包裝到NSOperation中,然後依次執行它們。

+0

我正在玩這樣的實現,但它不會工作。問題在於傳入'dispatch_group_async'的塊幾乎立即完成(它只是將異步調用設置爲'method1WithCompletion',它不會等待完成)。所以方法1和2幾乎是瞬間調用的,當它們全部完成時調用3。我正在使用[this](https://gist.github.com/anonymous/ad17ae377b58002ec2d0)進行測試,並且您可以看到它不起作用:( – cjwirth 2015-02-11 01:41:57

+0

同樣的道理,我認爲'NSOperation'會有相同的作爲GCD等待完成的問題......我沒有用過那麼多,所以我可能是錯的,雖然 – cjwirth 2015-02-11 01:42:47

+0

是的,我檢查了你的測試代碼,你完全正確!至於'NSOperation',簡而言之,串行操作隊列直到前一個操作完成纔會開始下一個排隊操作,並且當method1..2完成時你可以改變操作的完成狀態,並且操作依賴於它們的執行順序,也需要檢查。稍後再做一些示例代碼 – 2015-02-11 10:59:30