I don’t think I understand how blocks work exactly in this scenario. I’m trying to get the location from CLGeocoder and save the MKPlacemark after the block is finished. So in this method:
- (MKPlacemark *)placeMarkFromString:(NSString *)address {
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
__block MKPlacemark *place;
[geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {
[placemarks enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSLog(@"%@", [obj description]);
}];
// Check for returned placemarks
if (placemarks && [placemarks count] > 0) {
CLPlacemark *topResult = [placemarks objectAtIndex:0];
// Create an MKPlacemark and add it to the mapView
place = [[MKPlacemark alloc] initWithPlacemark:topResult];
[self.mapView addAnnotation:place];
}
if (error) {
NSLog(@"Error: %@", [error localizedDescription]);
}
}];
NSLog(@"%@", [place description]);
return place;
}
When I run my code, the MKPlacemark place does get added to the map. However, if I log the value, it is NULL. I think that might be because the block doesn’t get executed right away right? So my NSLog might be executed first, and then the completionHandler runs. However, how would I return the MKPlacemark from this method so I can use that value elsewhere in my code? thanks.
If you want to retain “place” create an ivar/property on self (whatever self is) for it. declare it as a __block variable. Then do:
self.place = [[MKPlacemark alloc] initWithPlacemark:topResult];
Or you could create an NSArray ivar if you wanted to keep track of multiple places and then just add the object to the array each time the block executes.
And yes, your NSLog(@”%@”, [place description]); will run before the block executes.
EDIT: If you want to “return” place from this method you’d need to make your method a block method something like this: