为什么这个CLLocationCoordinate2D变量不可分配?

时间:2013-08-12 01:05:40

标签: ios objective-c objective-c-blocks

我有一个地理编码方法,我想让它返回它为我生成的CLLocationCoordinate2D。

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

然而,行coordinate = location.coordinate会产生错误。 XCode说coordinate是一个不可分配的变量。有谁看到我做错了什么?

更新

按照塞巴斯蒂安的建议,我得到了编译的代码,但coordinate没有正确设置。如果您查看我在方法中放入的两个NSLog语句,第一个会打印出我需要分配给coordinate的正确坐标,但是只要if语句退出,coordinate回到被设置为(0,0)。第二个NSLog语句打印(0,0)。有谁知道如何解决这个问题?

- (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 个答案:

答案 0 :(得分:0)

如果要分配给在块范围之外定义的变量,则必须使用__block关键字:

__block CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(0,0);

查看Blocks and Variables section

Apple's Block Programming Topics

关于编译时未设置的变量:

geocodeAddressDictionary:completionHandler:以异步方式运行。这意味着它会立即返回,但是当结果可用时,块会在稍后执行。您需要更改调用方法的方式。目前你可能正在做这样的事情

self.myCoordinate = [self geocode];

你需要做的更像是这样:

- (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");
        }
    }];
}

运行[self geocode]会立即返回,并且在块运行时将设置myCoordinate

如果您这样做,请注意这可能会导致参考周期,因为块会保留self。