Why is this CLLocationCoordinate2D variable unassi

2019-02-20 22:01发布

I have a geocoder method and I want it to return the CLLocationCoordinate2D that it generates for me.

- (CLLocationCoordinate2D)geocode{
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(0,0);

    [geocoder geocodeAddressDictionary:self.placeDictionary completionHandler:^(NSArray *placemarks, NSError *error) {
        if([placemarks count]) {
            CLPlacemark *placemark = [placemarks objectAtIndex:0];
            CLLocation *location = placemark.location;
            coordinate = location.coordinate;
        } else {
            NSLog(@"error");
        }
    }];

    return coordinate;
}

The line coordinate = location.coordinate produces an error however. XCode says coordinate is an unassignable variable. Anyone see what I'm doing wrong?

update:

After following sebastian's advice, I got the code to compile, however, coordinate is not being properly set. If you take a look at both of the NSLog statements i put in the method, the first one prints out the correct coordinates that I need assigned to coordinate, however as soon as the if statement exits, coordinate goes back to being set to (0,0). The second NSLog statement prints (0,0). Anyone know how I can fix this?

- (CLLocationCoordinate2D)geocode{
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    __block CLLocationCoordinate2D geocodedCoordinate = CLLocationCoordinate2DMake(0,0);

    [geocoder geocodeAddressDictionary:self.placeDictionary completionHandler:^(NSArray *placemarks, NSError *error) {
        if([placemarks count]) {
            CLPlacemark *placemark = [placemarks objectAtIndex:0];
            CLLocation *location = placemark.location;
            geocodedCoordinate = location.coordinate;
            NSLog(@"%f, %f", coordinate.longitude, coordinate.latitude); 
        } else {
            NSLog(@"error");
        }
    }];

    NSLog(@"%f, %f", coordinate.longitude, coordinate.latitude); 
    return coordinate;
}

1条回答
劫难
2楼-- · 2019-02-20 22:25

You have to use the __block keyword if you want to assign to a variable that was defined outside the block's scope:

__block CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(0,0);

Have a look at the Blocks and Variables section of Apple's Block Programming Topics

About the variable not getting set when it compiles:

geocodeAddressDictionary:completionHandler: runs asynchronously. That means it returns immediately but the block gets executed later, when the results are available. You need to change the way you call your methods. At the moment you are probably doing something like this

self.myCoordinate = [self geocode];

What you have to do is more like this:

- (void)geocode{
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    [geocoder geocodeAddressDictionary:self.placeDictionary completionHandler:^(NSArray *placemarks, NSError *error) {
        if([placemarks count]) {
            CLPlacemark *placemark = [placemarks objectAtIndex:0];
            CLLocation *location = placemark.location;
            self.myCoordinate = location.coordinate;
            NSLog(@"%f, %f", coordinate.longitude, coordinate.latitude); 
        } else {
            NSLog(@"error");
        }
    }];
}

Running [self geocode] returns immediately and myCoordinate will be set when the block runs.

If you are doing it that way, note that this could lead to a reference cycle, because self is being retained by the block.

查看更多
登录 后发表回答