假如現在任務mainTask需要在有task1, task2, task3...等多個任務執行完畢后才能執行, 而這多個任務是異步執行的, 我們并不知道哪一個先執行完畢, 那么該怎么辦呢?此時我們已AFNetWorking為例進行解決.
NSArray*urlStrings = @[task1, task2, task3, ....];
for (id task in arr) {
? ? ? 異步執行task
? ? ? AFHTTPSessionManager *manager = [AFSingletonShare shareAFHTTPSessionManager];
? ? ? [manager POST:urlStr parameters:nil constructingBodyWithBlock:nil progress:nil ? ? ? ? ? ?success:^(NSURLSessionDataTask * _Nonnull task, id? _Nullable responseObject) {
? ? ? ? ? ? ? ?NSLog(@"成功操作");
? ? ? } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
? ? ? ? ? ? ? ?NSLog(@"失敗操作");
? ? ? }];
}
//執行mainTask
此時因為for循環中的任務因為是異步執行,我們并不知道哪個最后執行完畢. 所以此時我們需要使用到dispatch_group了, 在dispatch_group任務組內的任務都完成的時候會通過同步或者異步的方式通知你, 因此我們只需要將我們的異步任務添加到dispatch_group任務組中即可.?
下面我們開始說說dispatch_group提供的兩種方式區別:
方式一: dispatch_group_wait, 這種方式會阻塞當前線程, 在使用時通常會把它放到子線程中, 以避免阻塞主線程. 此時, 我們要注意的是需要我們手動控制進入和結束子線程操作,請看示例
步驟(1):
//主線程
? ? ? ? dispatch_group_t taskGroup = dispatch_group_create();
? ? ? ? for (id task in arr) {
? ? ? ? ? ? ? ? //異步執行task
? ? ? ? ? ? ? dispatch_group_enter(taskGroup); //進入
? ? ? ? ? ? ? ? ?AFHTTPSessionManager *manager = [AFSingletonShare shareAFHTTPSessionManager];
? ? ? ? ? ? ? ?[manager POST:urlStr parameters:nil constructingBodyWithBlock:nil progress:nil ? ? ? ? ? ?success:^(NSURLSessionDataTask * _Nonnull task, id? _Nullable responseObject) {
? ? ? ? ? ? ? ? ? ? ? ?NSLog(@"成功操作");
? ? ? ? ? ? ? ? ? ? ? dispatch_group_leave(taskGroup);//離開
? ? ? ? ? ? ? ? } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
? ? ? ? ? ? ? ? ? ? ? ?NSLog(@"失敗操作");
? ? ? ? ? ? ? ? ? ? ? dispatch_group_leave(taskGroup);離開
? ? ? ? ? ? ? ?}];
? ? ? ? ?}
步驟(2):隨后開始執行mainTask
dispatch_group_wait(taskGroup, DISPATCH_TIME_FOREVER);
dispatch_async(dispatch_get_main_queue(), ^{
? ? ? ? //執行mainTask
});
方式二:dispath_group_notify, 因為通過異步的方式通知, 所以不會阻塞主線程 .
步驟(1):同方式一步驟(1)
步驟(2):
dispatch_group_notify(taskGroup, dispatch_get_main_queue(), ^{
//執行mainTask
});