2012-02-27 1 views
2

J'ai le bit de code suivant dans une méthode de classeEn attendant CLGeocoder pour terminer sur un dénombrement simultané

NSDictionary *shopAddresses = [[NSDictionary alloc] initWithContentsOfFile:fileName]; 
NSMutableArray *shopLocations = [NSMutableArray arrayWithCapacity:shopAddresses.count]; 

[shopAddresses enumerateKeysAndObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id key, ShopLocation *shopLocation, BOOL *stop) { 
    CLGeocoder *geocoder = [[CLGeocoder alloc] init]; 
    [geocoder geocodeAddressString:shopLocation.address completionHandler:^(NSArray *placemarks, NSError *error) { 
     if (error) { 
      NSLog(@"Geocode failed with error: %@", error); 
     } 
     else { 
      shopLocation.placemark = [placemarks objectAtIndex:0]; 
     } 
     [shopLocations addObject:shopLocation]; 
    }]; 
} 

Après l'exécution de ce code, je veux retourner le tableau shopLocations comme résultat pour la méthode. Cependant, j'ai besoin d'attendre d'une manière ou d'une autre que toutes les recherches de géocodeur soient terminées si je ne veux pas que le tableau soit vide.

Comment est-ce que je peux faire ceci?

J'ai essayé différentes approches GCD, mais je n'ai pas réussi jusqu'à présent.

Répondre

6

Ceci peut être géré par le dispatch_group _... fonctions:

… 
dispatch_group_t group = dispatch_group_create(); 

[shopAddresses enumerateObjectsUsingBlock:^(id key, NSUInteger idx, BOOL *stop) { 

    dispatch_group_enter(group); 

    CLGeocoder *geocoder = [[CLGeocoder alloc] init]; 
    [geocoder geocodeAddressString:shopLocation.address completionHandler:^(NSArray *placemarks, NSError *error) { 
     if (error) { 
      NSLog(@"Geocode failed with error: %@", error); 
     } 
     else { 
      shopLocation.placemark = [placemarks objectAtIndex:0]; 
     } 
     [shopLocations addObject:shopLocation]; 

     dispatch_group_leave(group); 
    }]; 
}]; 

while (dispatch_group_wait(group, DISPATCH_TIME_NOW)) { 
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 
          beforeDate:[NSDate dateWithTimeIntervalSinceNow:1.f]]; 
} 
dispatch_release(group); 

… 

J'utilise ce genre de blocs pour accumuler des requêtes réseau.

J'espère que cela peut aider.

+0

C'était facile. Je n'ai pas pensé à utiliser les groupes d'expédition manuellement. –

+0

C'est l'une des solutions que j'ai essayées, mais sans succès. La fonction dispatch_group_wait a attendu pour toujours. Je pense que cela se produit car la fonction dispatch_group_leave est imbriquée dans le bloc du gestionnaire d'achèvement. – Beav

+0

Il est supposé attendre indéfiniment. Mais je viens de réaliser que la méthode '-geocodeAddressString: completionHandler:' exécute le bloc sur le thread principal. Et ma solution peut arrêter le runloop. Mais il y a aussi une solution pour cela et je vais modifier ma réponse ci-dessus. –

Questions connexes