需求場景:如,A網(wǎng)絡請求 和 B網(wǎng)絡請求完成后,刷新界面。
方案一:通過GCD的信號量semaphore
- (void)twoRequest {
// 創(chuàng)建 任務組
dispatch_group_t group = dispatch_group_create();
// 獲取一個全局隊列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 創(chuàng)建 信號量
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
// 執(zhí)行循序1
dispatch_group_async(group, queue, ^{
// 第一個請求
[[NetworkEngine shareEngine] fetch... completionBlock:^(BOOL isSucceeded, id responseObject, NSError *error) {
if (isSucceeded) {
// Todo
} else {
// 異常處理
}
// 執(zhí)行順序4/6
dispatch_semaphore_signal(semaphore);
}];
});
// 執(zhí)行循序2
dispatch_group_async(group, queue, ^{
// 第二個請求
[[NetworkEngine shareEngine] fetch... completionBlock:^(BOOL isSucceeded, id responseObject, NSError *error) {
if (isSucceeded) {
// Todo
} else {
// 異常處理
}
// 執(zhí)行順序4/6
dispatch_semaphore_signal(semaphore);
}];
});
dispatch_group_notify(group, queue, ^{
// 執(zhí)行循序3
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
// 執(zhí)行順序5
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
// 執(zhí)行順序7
dispatch_async(dispatch_get_main_queue(), ^{ 刷新界面 });
});
}
信號量可以用車庫中的空閑車位來表示。當要往車庫停車時,如果車庫已滿,則需等待(阻塞線程)。
- 關于信號量的三個方法
1.創(chuàng)建一個車庫,value表示車庫中空閑車位的數(shù)量
dispatch_semaphore_create(long value);
2.往車庫里停一輛車,如果沒有空車位,則一直會等待在車庫外,等待時間為dispatch_time_t timeout,如果有空車位則停車,減少一個空車位
dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
3.從車庫中開走一輛車,增加一個空閑車位
dispatch_semaphore_signal(dispatch_semaphore_t dsema);
- 關于任務組的三個方法
1、函數(shù)dispatch_group_notify(group1, queue1,block);
監(jiān)聽group組中任務的完成狀態(tài),當所有的任務都執(zhí)行完后,觸發(fā)block塊,執(zhí)行總結性處理。
2、函數(shù)dispatch_group_wait(group1, DISPATCH_TIME_FOREVER)
當前線程暫停,等待此函數(shù)上面的任務執(zhí)行完成后,線程才繼續(xù)執(zhí)行。
3、函數(shù)dispatch_group_async(group, queue, block);
將block任務添加到queue隊列,并被group組管理。
方案二: dispatch_group_enter
{
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group); // 任務 + 1
[[NetworkEngine shareEngine] fetch... completionBlock:^(BOOL isSucceeded, id responseObject, NSError *error) {
if (isSucceeded) {
// Todo
} else {
// 異常處理
}
dispatch_group_leave(group); // 任務 - 1
}];
dispatch_group_enter(group); // 任務 + 1
[[NetworkEngine shareEngine] fetch... completionBlock:^(BOOL isSucceeded, id responseObject, NSError *error) {
if (isSucceeded) {
// Todo
} else {
// 異常處理
}
dispatch_group_leave(group); // 任務 - 1
}];
dispatch_group_notify(group, dispatch_get_main_queue(), ^(){
NSLog(@"Group End!");
});
}
簡單來說,就是 dispatch_group_enter會對 group 的內(nèi)部計數(shù) +1,dispatch_group_leave 會對 group 的內(nèi)部計數(shù) -1,就類似以前的 retain和 release方法。也就是維護了一個計數(shù)器。