2012-09-03 11 views
5

Dentro de la siguiente función, he usado un bloque. Pero cuando llamo a esta función, se devuelve incluso antes de que se ejecute el bloque. Entendí que Block inturn usa los hilos y se ejecuta por separado para que la función no espere a que vuelva. Pero, ¿hay alguna otra forma en que pueda hacer que la ejecución de la función espere, o de cualquier otra manera para lograr la funcionalidad de este bloque sin usar el bloque en sí?¿Cómo hacer una llamada a la función en ios para esperar, hasta que el bloque dentro de esa función se ejecute por completo?

-(int)findCurrentZip 
{ 
     CLLocation *userLocation = [[CLLocation alloc] initWithLatitude:[self findCurrentLatitude] 
                   longitude:[self findCurrentLongitude]]; 
     int zipcode; 
     self.myGeocoder = [[CLGeocoder alloc] init]; 
     [self.myGeocoder 
     reverseGeocodeLocation:userLocation 
     completionHandler: (id)^(NSArray *placemarks, NSError *error) { 
      if (error == nil && [placemarks count] > 0) 
      { 
       NSLog(@"Placemarks: %@",placemarks); 
       CLPlacemark *placemark = [placemarks objectAtIndex:0]; 
       NSLog(@"Country = %@", placemark.country); 
       NSLog(@"Postal Code = %@", placemark.postalCode); 
       zipcode = (int)placemark.postalCode; 
       NSLog(@"Locality = %@", placemark.locality); 
       NSLog(@"Country%@",[placemarks lastObject]); 
      } 
      else if (error == nil && [placemarks count] == 0) 
      { 
       NSLog(@"No results were returned."); 
      } 
      else if (error != nil) 
      { 

      } 
     }]; 

     return zipcode; 
    } 
+0

al igual que una nota. hay una razón por la cual postalCode es un NSString en CLPlacemark. ¡Los códigos postales pueden comenzar con un 0! –

+2

oh, y '(int) placemark.postalCode' no convierte ese NSString en un int ;-) –

Respuesta

8

En primer lugar, le sugiero que reconsidere su diseño. En lugar de devolver el valor zipCode de este método, llame a algún otro método en el completionHandler (cree un protocolo/delegado o lo que sea). El método reverseGeocodeLocation:: puede tomar algún tiempo y no desea pausar la ejecución del subproceso principal esperando el resultado.

Si desea bloquear, puede considerar el uso (¿abuso?) De un dispatch_semaphore_t. Inicialícelo en 0 y dispatch_semaphore_wait después de la llamada al reverseGeocodeLocation::. En la terminaciónHandler lo señaliza con dispatch_semaphore_signal.

Más información: Using Dispatch Semaphores to Regulate the Use of Finite Resources

edit: y al igual que otros sugirieron, declarar Código postal con un calificador __block

+0

Tampoco use el patrón 'en espera', porque cuando llama accidentalmente a' findCurrentZip' del hilo principal, su aplicación quedarse atascado hasta que encuentre el código postal. Mal diseño ... – robertvojta

+0

Sí, Seems Protocol/Delegate es la técnica optimizada y correcta para este escenario. –

Cuestiones relacionadas