7

के लिए प्रतीक्षा नहीं करता है दो समवर्ती पृष्ठभूमि कार्यों को दो अलग-अलग सरणी को पैच करने की आवश्यकता होती है जिन्हें एक dispatch_group_notify ब्लॉक में विलय करने की आवश्यकता होती है। समस्या यह है कि वह पहला ब्लॉक पार हो गया है लेकिन dispatch_group_notify निष्पादन की प्रतीक्षा किए बिना पार हो गया है दूसरे पृष्ठभूमि कार्य का। उनके बीच एकमात्र अलग यह है कि पहला व्यक्ति स्थानीय खोज करता है और दूसरा वेब सेवा पर रिमोट कॉल करता है। कोई संकेत क्यों दूसरा दूसरा कूद गया है?dispatch_group_notify एक dispatch_group_async

संपादित करें: मैंने 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, 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 
}); 

और दूरदराज खोज विधि इस

- (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

इसका कारण यह है अपने getPath विधि एसिंक्रोनस रूप से चलाता है की तरह लग रहा है। समूह को छोड़ने के लिए आपको इसकी आवश्यकता नहीं है जब तक कि पूरा समापन ब्लॉक नहीं चलता है। तो dispatch_group_async करने के बजाय, आपको मैन्युअल रूप से dispatch_group_enter और dispatch_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 को बदल सकता है:

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

वैकल्पिक उत्तरों के साथ प्रतिक्रिया और महान स्पष्टीकरण के लिए आपको बहुत बहुत धन्यवाद =) –

+0

I hav मैं इस तरह के कुछ लंबे समय के लिए खोज रहा था। :) थम्स अप। : डी – riyaz

+0

क्या आप अभी भी समूह समापन के अधिसूचित होने के लिए dispatch_group_notify का उपयोग करते हैं? –

संबंधित मुद्दे