两个并发的后台任务需要修补需要在dispatch_group_notify块中合并的两个单独的阵列.问题在于,超出了第一个块但超出了dispatch_group_notify而没有等待执行第二个后台任务.
它们之间唯一不同的是,第一个进行本地搜索,第二个远程调用Web服务.任何线索为什么第二个跳过?
它们之间唯一不同的是,第一个进行本地搜索,第二个远程调用Web服务.任何线索为什么第二个跳过?
编辑:我也尝试使用dispatch_barrier_async在https://stackoverflow.com/a/19580584/859742中提到的方法,但仍然相同.
dispatch_group_t taskGroup = dispatch_group_create(); dispatch_queue_t mainQueue = dispatch_get_main_queue(); __block NSArray *localAddresses; __block NSArray *remoteAddresses; //Get local array in the background dispatch_group_async(taskGroup,mainQueue,^{ //localAddresses is set }); //get remote array from server dispatch_group_async(taskGroup,^{ [[MDAddressManager instance] searchForPlacesContainingText:query location:alocation completion:^(NSArray* addresses,MDError *error){ //remoteAddresses is set }); //Merge two arrays dispatch_group_notify(taskGroup,^{ //remoteAddresses and local addresses are merged });
- (void)searchForPlacesContainingText:(NSString *)searchText location:(CLLocation *)alocation completion:(MDAddressManagerBlock)completionBlock { NSDictionary *parameters = [[NSMutableDictionary alloc] init]; [parameters setValue:searchText forKey:@"input"]; [[MDHTTPClient sharedHTTPClient] getPath:@"v1/remotePlaces.json" parameters:parameters success:^(AFHTTPRequestOperation *operation,id dict) { if ([MDHTTPClient isResponseValid:dict]) { completionBlock(returnArray,nil); } else { completionBlock(nil,nil); } } failure:^(AFHTTPRequestOperation *operation,NSError *error) { EDLog(@"%@",error); completionBlock(nil,[MDError errorAFNetworking:error]); }]; }
解决方法
这是因为您的getPath方法异步运行.在完成块运行之前,您需要它不离开组.因此,您应该手动调度dispatch_group_enter和dispatch_group_leave,而不是执行dispatch_group_async.
您可以从以下位置更改代码:
dispatch_group_async(taskGroup,^{ [[MDAddressManager instance] searchForPlacesContainingText:query location:alocation completion:^(NSArray* addresses,MDError *error){ //remoteAddresses is set }]; });
至:
dispatch_group_enter(taskGroup); [[MDAddressManager instance] searchForPlacesContainingText:query location:alocation completion:^(NSArray* addresses,MDError *error){ //remoteAddresses is set dispatch_group_leave(taskGroup); });
这将确保您在调用完成块之前不离开组.
或者,您可以更改searchForPlacesContainingText以使用dispatch_group_t参数:
- (void)searchForPlacesContainingText:(NSString *)searchText location:(CLLocation *)alocation group:(dispatch_group_t)group completion:(MDAddressManagerBlock)completionBlock { dispatch_group_enter(group); NSDictionary *parameters = [[NSMutableDictionary alloc] init]; [parameters setValue:searchText forKey:@"input"]; [[MDHTTPClient sharedHTTPClient] getPath:@"v1/remotePlaces.json" parameters:parameters success:^(AFHTTPRequestOperation *operation,id dict) { if ([MDHTTPClient isResponseValid:dict]) { completionBlock(returnArray,nil); } else { completionBlock(nil,nil); } dispatch_group_leave(group); } failure:^(AFHTTPRequestOperation *operation,NSError *error) { EDLog(@"%@",error); completionBlock(nil,[MDError errorAFNetworking:error]); dispatch_group_leave(group); }]; }
并更改您的调用,以便它不执行dispatch_group_async,而只是传递taskGroup参数:
[[MDAddressManager instance] searchForPlacesContainingText:query location:alocation group:taskGroup completion:^(NSArray* addresses,MDError *error) { //remoteAddresses is set });