I have some concurrent operation for the data processing. During the processing I need to retrieve the reverse geocoding for the location. It is known that - (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler also performs geocoding request in background thread and returns immediately after the call. When geocoded finishes request it executes the completion handler on the main thread. How can I block my concurrent operation until the geocoder retrieves the result?
__block CLPlacemark *_placemark
- (NSDictionary *)performDataProcessingInCustomThread
{
NSMutableDictionary *dict = [NSMutableDictionary alloc] initWithCapacity:1];
// some operations
CLLocation *location = [[CLLocation alloc] initWithLatitude:40.7 longitude:-74.0];
[self proceedReverseGeocoding:location];
// wait until the geocoder request completes
if (_placemark) {
[dict setValue:_placemark.addressDictionary forKey:@"AddressDictionary"];
return dict;
}
- (void)proceedReverseGeocoding:(CLLocation *)location
{
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
if ([error code] == noErr) {
_placemark = placemarks.lastObject;
}
}];
}
To achieve this we can use
dispatch_semaphore_t. First of all we need to add semaphore to the class:When we are processing data and ready to receive the geocoding data, we should create dispatch semaphore and start to wait a signal:
At the end of CLGeocodeCompletionHandler all we need is to send the signal to resume the data processing:
After this the data processing will continue