常用的幾個方法
- dispatch_group_enter :通知 group,下個任務要放入 group 中執行了
- dispatch_group_leave: 通知 group,任務成功完成,要移除,與 enter成對出現
- dispatch_group_wait: 在任務組完成時調用,或者任務組超時是調用(完成指的是enter和leave次數一樣多)
- dispatch_group_notify: 只要任務全部完成了,就會在最后調用
具體情況分析
實際應用
我們就可以使用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 的控制使用