2012-09-03 11 views
5

Wewnątrz poniższej funkcji użyłem bloku. Ale kiedy wywołuję tę funkcję, jest ona zwracana nawet przed wykonaniem bloku. Zrozumiałem, że Block Inturn używa wątków i wykonuje oddzielnie, aby funkcja nie czekała na powrót. Ale, czy jest jakiś inny sposób, w jaki mógłbym sprawić, aby funkcja czekała, czy jakikolwiek inny sposób na osiągnięcie funkcjonalności tego bloku bez korzystania z samego bloku?Jak wywołać funkcję w ios, aby czekać, aż blok wewnątrz tej funkcji zostanie wykonany całkowicie?

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

tylko jako notatkę. istnieje powód, dla którego PostalCode jest NSString w CLPlacemark. Kody pocztowe można rozpoczynać od 0! –

+2

oh, a '(int) znak_ miejsca_pionowego.postalCode' nie konwertuje tego NSString na int ;-) –

Odpowiedz

8

Po pierwsze, proponuję przemyśleć twój projekt. Zamiast zwracania wartości zipCode z tej metody, wywołaj inną metodę w completHandler (utwórz protokół/delegat lub cokolwiek innego). Metoda reverseGeocodeLocation:: może zająć trochę czasu i nie należy wstrzymywać wykonywania głównego wątku oczekującego na wynik.

Jeśli jednak chcesz zablokować, możesz rozważyć użycie (nadużywanie?) Numeru dispatch_semaphore_t. Zainicjuj go na 0 i dispatch_semaphore_wait po połączeniu z reverseGeocodeLocation::. W zakończeniuHandler sygnalizuje to przy pomocy dispatch_semaphore_signal.

Więcej informacji: Using Dispatch Semaphores to Regulate the Use of Finite Resources

edit: i jak inni sugerują, oświadczyć ZIPCODE z kwalifikatorem __block

+0

Również nie używaj wzorca" oczekującego ", ponieważ gdy przypadkowo nazwiesz' findCurrentZip' przypadkowo z głównego wątku, twoja aplikacja utknąć, aż znajdziesz kod pocztowy. Zły projekt ... – robertvojta

+0

Tak, Wydaje się, że Protokół/Delegat jest zoptymalizowaną i odpowiednią techniką dla tego scenariusza .. –

Powiązane problemy