两个并发的后台任务需要修补需要在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
});