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メソッドは、completedHandler がレスポンスを処理する前に戻ります。メソッドで返される都市に依存するのではなく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 に答える