7

두 개의 동시 백그라운드 작업이 dispatch_group_notify 블록에서 병합되어야하는 두 개의 개별 어레이를 패치해야합니다. 문제는 첫 번째 블록이 초과되었지만 dispatch_group_notify가 실행을 기다리지 않고 초과되었습니다. 두 번째 배경 작업의 그들 사이의 유일한 차이점은 첫 번째 검색은 로컬 검색이고 두 번째 검색은 웹 서비스에 대한 원격 호출입니다. 두 번째 검색이 왜 튀어 나왔는지 전혀 모르십니까?dispatch_group_notify가 하나의 dispatch_group_async를 대기하지 않음

편집 : 나는 또한 https://stackoverflow.com/a/19580584/859742에서 설명한 접근법을 dispatch_barrier_async를 사용했지만 여전히 동일하게 시도했습니다.

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, mainQueue, ^{ 
[[MDAddressManager instance] searchForPlacesContainingText:query 
                 location:alocation 
                completion:^(NSArray* addresses, MDError *error){ 
     //remoteAddresses is set 
}); 


//Merge two arrays 
dispatch_group_notify(taskGroup, mainQueue, ^{ 
    //remoteAddresses and local addresses are merged 
}); 

는 원격 검색 방법은 getPath 방법은 비동기 적으로 실행되기 때문에 이것은이

- (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]); 
}]; 
} 

답변

13

것 같습니다. 완료 블록이 실행될 때까지 그룹을 떠나지 않아야합니다. 그러므로 dispatch_group_async을 수행하는 것보다 dispatch_group_enterdispatch_group_leave을 수동으로 사용해야합니다.

당신은에서 코드를 변경할 수 있습니다

dispatch_group_async(taskGroup, mainQueue, ^{ 
    [[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); 
}); 

완료 블록이 호출 될 때까지 당신이 카페에서 탈퇴하지 않도록 것이다.


또는, dispatch_group_t 매개 변수를 사용하는 searchForPlacesContainingText을 변경할 수 있습니다 : 그것은 dispatch_group_async하지 않도록

- (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); 
    }]; 

} 

을하고 호출을 변경, 오히려 단지 taskGroup 매개 변수를 전달합니다

[[MDAddressManager instance] searchForPlacesContainingText:query 
                location:alocation 
                group:taskGroup 
               completion:^(NSArray* addresses, MDError *error) { 
    //remoteAddresses is set 
}); 
+0

답장을 보내 주시면 감사하겠습니다. 대체 답변 =) –

+0

I hav 이런 일을 오랫동안 찾고있었습니다. :) 위로 엄지. : D – riyaz

+0

그룹 완료 알림을 받기 위해 여기에서도 dispatch_group_notify를 사용하고 있습니까? –