2010-11-16 5 views
0

J'ai eu quelques problèmes avec les rappels de CLLocationManager
Quelle est la meilleure façon d'attendre un rappel asynchrone?Attendre un rappel asynchrone - Objective-C

Voici ce que je veux essentiellement faire:

 

- (NSString *)getCurrentCity 
{ 
     [self.locationManager startUpdatingLocation]; 
     // Wait for coordonate in callbacks 
     self.geocoder = [MKReverseGeocoder alloc] initWithCoordonate:self.newCoordonate]; 
     [self.geocoder start]; 
     // Wait for information with MKReverse callbacks 
     return self.currentCity; 
} 
// Callbacks methods of MKReverseGeocoder and CLLocationManager 
- (void)locationManager:(CLLocationManager *)manager 
    idUpdateToLocation:(CLLocation *)newLocation 
      fromLocation:(CLLocation *)oldLocation 
{ 
     CLLocationCoordinate2D newCoordonate = newLocation.coordinate; 
     self.currentCoordonate = &newCoordonate; 
} 

- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder 
     didFindPlacemark:(MKPlacemark *)placemark 
{ 
     self.currentCity = placemark.locality; 
} 

Où self.currentCity et self.newCoordonate est un attribut dans ma classe.

J'ai essayé quelques trucs comme Thread et/ou synchronisé mais je n'ai pas réussi à ne pas revenir avant que tout soit fini.

Meilleures salutations

+0

self.currentCoordonate = & newCoordonate; Cela me fait peur à plusieurs niveaux –

+0

Le but du rappel asynchrone est que vous n'avez pas à l'attendre. – koo

Répondre

2

Vous n'attendez pas à compléter, vous gérez la mise à jour lorsque le asynchrone locationmanager:didUpdatefromLocation: est appelé. C'est le but de la programmation asynchrone. :)

+0

Je suis d'accord; En réalité . Je veux juste appeler une méthode pour obtenir une information en passant par les rappels asynchrones. Et si je pouvais passer la synchronisation je serais gentil pour moi je pense – klefevre

+0

Une façon pourrait être d'écrire une classe d'emballage 'GPSManager' ou quelque chose comme ça. Il gère le contenu de CLLocationManager et expose deux propriétés comme 'positionAvailable' et' currentPosition' à utiliser dans votre autre code. –

+0

J'ai déjà essayé ça mais c'est le même point ... Comment savoir si ma propriété a changé? Cela fonctionne aussi de manière asynchrone. – klefevre

1

Chaque fois que vous bloquez le thread principal, votre application ne répond plus (au mieux) et sera rejetée par le système (c'est-à-dire tuée - dans le pire des cas).

Pour les API asynchrones, le plus tendance est d'isoler tous du filetage ou faire la queue ou tout autre mécanisme que vous utilisez pour obtenir le travail hors du fil conducteur dans une classe qui prend soin de rendezvousing au thread principal au besoin . Pour un exemple, voir NSFileHandle. Il a une méthode readInBackgroundAndNotify:. Lorsqu'il est utilisé, l'instance NSFileHandle crée en interne un thread, utilise ce thread pour lire tout ce qui est nécessaire, puis utilise quelque chose comme performSelectorOnThread: pour envoyer la notification au thread - généralement le thread principal - qui a appelé readInBackgroundAndNotify: en premier lieu. Ainsi, les utilisateurs de la classe ne doivent pas gérer le thread mais la classe ne bloque pas la boucle d'événement principal.


BTW:

{ 
    CLLocationCoordinate2D newCoordinate = newLocation.coordinate; 
    self.currentCoordonate = &newCoordinate; 
} 

Ceci est complètement faux et un moyen sûr de garantir un accident ou d'un comportement non défini. &newCoordinate donne l'adresse de newCoordinate, mais cette structure est sur la pile. Dès que cette méthode revient, le contenu de cette structure va être détruit.

+0

Je le fais parce que je déclare un pointeur de CLLocationCoordinate2D. Donc CLLocationCoordinate2D * newCoordinate = & newCoordinate; fonctionne parfaitement – klefevre

+1

@ KL94: Oui, c'est un pointeur, et bien sûr, votre code est accepté par le système de type Objective-C. Il y a plus qu'un programme de travail que de s'assurer que vos types correspondent.Prendre un pointeur vers une variable automatique et la stocker dans une variable d'instance est un comportement non défini - c'est un bug ou un crash qui attend de se produire. Des questions à vous poser pour trouver la bonne solution: * Pourquoi * cette variable d'instance est-elle un pointeur? S'il y a une raison à cela, quelle en est la raison? Vous devez concevoir votre code correctement autour de cette contrainte. Sinon, n'en faites pas un pointeur. – Chuck

Questions connexes