1

我在 iOS 上的 Objective C 中使用反向地理编码返回城市时遇到问题。我可以在completionHandler 中记录城市,但是如果从另一个函数调用它,我似乎无法弄清楚如何将它作为字符串返回。

city 变量是在头文件中创建的 NSString。

- (NSString *)findCityOfLocation:(CLLocation *)location
{

    geocoder = [[CLGeocoder alloc] init];
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {

        if ([placemarks count])
        {

            placemark = [placemarks objectAtIndex:0];

            city = placemark.locality;

        }
    }];

    return city;

}
4

2 回答 2

7

你的设计不正确。

您无法在方法中同步返回值,因为您正在执行异步调用。

completionHandler是一个将来会被调用的块,因此您必须更改代码的结构以在调用该块时处理结果。

例如,您可以使用回调:

- (void)findCityOfLocation:(CLLocation *)location { 
    geocoder = [[CLGeocoder alloc] init];
    typeof(self) __weak weakSelf = self; // Don't pass strong references of self inside blocks
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
        if (error || placemarks.count == 0) {
           [weakSelf didFailFindingPlacemarkWithError:error]; 
        } else {
            placemark = [placemarks objectAtIndex:0];
            [weakSelf didFindPlacemark:placemark];
        }
    }];
}

- (void)didFindPlacemark:(CLPlacemark *)placemark {
     // do stuff here...
}

- (void)didFailFindingPlacemarkWithError:(NSError *)error {
    // handle error here...
}

或者一个块(我通常更喜欢)

- (void)findCityOfLocation:(CLLocation *)location completionHandler:(void (^)(CLPlacemark * placemark))completionHandler failureHandler:(void (^)(NSError *error))failureHandler { 
    geocoder = [[CLGeocoder alloc] init];
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
        if (failureHandler && (error || placemarks.count == 0)) {
           failureHandler(error);
        } else {
            placemark = [placemarks objectAtIndex:0];
            if(completionHandler)
                completionHandler(placemark);
        }
    }];
}

//usage
- (void)foo {
   CLLocation * location = // ... whatever
   [self findCityOfLocation:location completionHandler:^(CLPlacemark * placemark) {
        // do stuff here...
   } failureHandler:^(NSError * error) {
        // handle error here...
   }];
}
于 2013-08-22T15:21:07.610 回答
1

反向地理编码请求异步发生,这意味着该findCityOfLocation方法将在 completionHandler 处理响应之前返回。我建议您不要依赖findCityOfLocation方法中返回的城市,而只需从 completionHandler 中对城市执行您想要的任何操作:

- (void)findCityOfLocation:(CLLocation *)location
{

    geocoder = [[CLGeocoder alloc] init];
    __weak typeof(self) weakSelf = self;
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {

        if ([placemarks count])
        {

            placemark = [placemarks objectAtIndex:0];

            weakSelf.city = placemark.locality;

            // we have the city, no let's do something with it
            [weakSelf doSomethingWithOurNewCity];
        }
    }];    
}
于 2013-08-22T15:23:12.413 回答