Question

I'm trying to forward geocode an address in iOS 5 using the CLGeocoder object and the put the resulting CLLocation in an instance variable. For some reason, I can set the instance variable and then call its getter, but the variable loses its value outside the scope of the Geocoder's completion handler.

I declared the variable in my .h file:

@property (nonatomic, strong) CLLocation *specifiedPosition;

Then synthesized it in my .m:

@synthesize specifiedPosition = _specifiedPosition;

And then tried to use the geocoder like this - the first NSLog returns a latitude and longitude, while the second does not:

-(void)getLatLong:(NSString *)locationText
{

if (!self.geocoder)
{
    self.geocoder = [[CLGeocoder alloc] init];
}

[self.geocoder geocodeAddressString:locationText completionHandler:^(NSArray *placemarks, NSError *error){

    if ( ([placemarks count] > 0) && (error == nil)) {

        self.specifiedPosition = [[placemarks objectAtIndex:0] location];
        NSLog(@"Specified Location variable is set to: %@", self.specifiedPosition);


    } else if (error == nil && [placemarks count] == 0){
        // TODO
        NSLog(@"Can't find data on the specificed location");
    }
    else if (error != nil){
        // TODO
        NSLog(@"An error occurred = %@", error);
    }

}];

NSLog(@"Specified Location variable is set to: %@", self.specifiedPosition);

}

I also tried a custom setter, but that didn't help:

-(void)setSpecifiedPosition:(CLLocation *)specifiedPosition
{
    _specifiedPosition = specifiedPosition;
}

Thanks in advance for your help!

Was it helpful?

Solution

I'm not familiar with this particular API, but the fact that it's taking a block called completionHandler very strongly suggests that this is an asynchronous operation. That is, your block will be invoked later (from the run loop). Your second NSLog in the source code is happening before the completionHandler is invoked, so it of course does not see the assignment since it hasn't happened yet.

Whatever you need to do once you have the specifiedPosition data, you should do it either inside of the completionHandler block, inside of -setSpecifiedPosition:, or somewhere else that is notified/triggered/called by one of those.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top