假如你說:像這樣的 GCD 多任務應用的場景不太算多, 我說:但這不是你不必知道怎麼去處理使用GCD處理多任務的事情的理由bash
其實在 iOS 開發中,像這樣的多任務處理,很簡單,由於 Apple 已經幫你封裝好了各類好用的 API,好比 GCD,如今我就說下具體的用法,全部的註釋都在代碼裏,寫的應該說是很詳細了。app
dispatch_group:建立任務組,而後異步執行加入到 group 的每一個任務,好比向 group 添加了3個任務,那麼這3個任務,會同時執行的,因爲每一個任務執行時間(耗時)不同,全部在全部的任務都執行結束後,會調用 dispatch_group_notify,能夠在這裏處理多個任務的結果。異步
dispatch_group_t group = dispatch_group_create(); // 建立任務組 dispatch_group_enter(group):// 建立任務,添加至 group dispatch_group_leave(group):// 任務結束,離開 groupui
// eg:
dispatch_group_enter(group);
// 建立任務(代碼)
...
dispatch_group_leave(group);
複製代碼
須要提醒的一點:使用dispatch_group建立的多任務,enter 和 leave 必須成對出現,不然,就呵呵了~spa
- (void)testGroupMultitask
{
NSLog(@"testGroupMultitask===============");
// 1.建立任務組
dispatch_group_t group = dispatch_group_create();
// 2.加入第一個任務
dispatch_group_enter(group);
NSMutableString *groupResult = [NSMutableString string];
// 模擬一個6秒的請求
[self fakeRequestWithDelay:6 result:^(NSString *string, NSError *error) {
/*
在這裏咱們設置的dispatch_group_wait時間是5秒,可是咱們這個任務的回調時間是6秒。因此結果是5秒事後wait超時,程序繼續往下執行,打印-> "wait時間已經到了"。
然而這個任務還在線程裏執行,一直到執行dispatch_group_leave這個任務才完成。
*/
NSString *result = [NSString stringWithFormat:@"任務組1完成 %@",string];
[groupResult appendString:result];
[groupResult appendString:@"\n"];
NSLog(@"------%@",string);
dispatch_group_leave(group);
}];
// 3.加入第二個任務
dispatch_group_enter(group);
/*
這裏我發現一個問題,我設置的dispatch_after的延時時間是3秒,也就是3秒後把block中的任務加入線程;
因此結果應該是在dispatch_group_wait時間內就能完成的,打印順序應該是在 "wait時間已經到了" 以前纔對, 可是打印的順序倒是先打印:"wait時間已經到了",而後打印:任務組2完成;
我猜想這個延時執行的代碼,是異步的等待,並非阻塞線程的,
*/
dispatch_time_t tt = dispatch_time(DISPATCH_TIME_NOW, 3*NSEC_PER_SEC);
dispatch_after(tt, dispatch_get_main_queue(), ^{
NSString *result = @"任務組2完成 delay 3 seconds";
[groupResult appendString:result];
[groupResult appendString:@"\n"];
NSLog(@"------%@",result);
dispatch_group_leave(group);
});
// 4.加入第三個任務
dispatch_group_enter(group);
NSString *result = @"任務組3完成";
[groupResult appendString:result];
[groupResult appendString:@"\n"];
NSLog(@"------%@",result);
dispatch_group_leave(group);
// 5.執行到這句代碼後會等待5秒,等待關聯的任務組group裏的全部任務完成。若是在5秒內都完成了,返回0並繼續執行;若是超時未完成,返回非0並繼續執行。因此任務組裏的任務不管是否所有完成,都會繼續執行。
int waitTime = 5;
dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(waitTime*NSEC_PER_SEC)));
NSLog(@"wait時間已經到了 %i seconds",waitTime);
// 6.notify會簡體關聯的任務組group中的全部任務是否都已完成(dispatch_group_enter和dispatch_group_leave匹配),完成了就會執行block
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"------全部任務組都完成了 \n %@",groupResult);
});
}
複製代碼
執行以上代碼,在控制檯輸出結果:線程
2016-07-10 17:53:10.397 | testGroupMultitask===============
2016-07-10 17:53:10.397 | ------任務組3完成
2016-07-10 17:53:15.399 | wait時間已經到了 5 seconds
2016-07-10 17:53:15.403 | ------任務組2完成 delay 3 seconds
2016-07-10 17:53:16.986 | ------delay 6 seconds
2016-07-10 17:53:16.987 |
------全部任務組都完成了
任務組3完成
任務組2完成 delay 3 seconds
任務組1完成 delay 6 seconds
複製代碼
對照打印的結果,能夠看出,上面group各任務的執行順序。code
最後再說下,enter和leave,不成對的後果:就是這個缺乏leave的任務,在開闢的子線程裏一直在等待結束,因此 dispatch_group_notify 一直收不到全部任務完成的通知orm