0
votes

I had some trouble with CLLocationManager callbacks
What is the best way to wait an asynchronous callback ?

Here is what i basically want to do :

 

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

Where self.currentCity and self.newCoordonate is an attribut in my classe.

I tried some tricks like Thread and/or synchronized but i didn't managed it to dont return before all is finish.

Best regards

2
self.currentCoordonate = &newCoordonate; That scares me on a number of levels - Joshua Weinberg
The whole point of async callback is that you don't have to wait for it. - koo

2 Answers

2
votes

You don't wait for it to complete, you handle the update when the asynchronous locationmanager:didUpdatefromLocation: is called. That's the point of asynchronous programming. :)

1
votes

Any time you block the main thread, your app becomes unresponsive (at best) and will get jettisoned by the system (i.e. killed -- in the worst case).

For asynchronous APIs, the easiest pattern is to isolate all of the threading or queueing or whatever mechanism you use to get the work off the main thread into a class that takes care of rendezvousing back to the main thread as needed.

For an example, look at NSFileHandle. It has a readInBackgroundAndNotify: method. When used, the NSFileHandle instance internally creates a thread, uses that thread to read whatever is needed, then uses something like performSelectorOnThread: to send the notification to the thread -- typically the main thread -- that called readInBackgroundAndNotify: in the first place.

By doing this, users of the class don't have to deal with the threading but the class doesn't block the main event loop.


BTW:

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

This is completely wrong and a sure fire way to guarantee a crash or undefined behavior. &newCoordinate gives the address of newCoordinate, but that structure is on the stack. As soon as that method returns, the contents of said structure are going to be trashed.