3

このシナリオでブロックがどのように機能するかを正確に理解していないと思います。CLGeocoderから場所を取得し、ブロックが終了した後にMKPlacemarkを保存しようとしています。したがって、この方法では:

- (MKPlacemark *)placeMarkFromString:(NSString *)address {
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    __block MKPlacemark *place;
    [geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {
        [placemarks enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
            NSLog(@"%@", [obj description]);
        }];

        // Check for returned placemarks
        if (placemarks && [placemarks count] > 0) {
            CLPlacemark *topResult = [placemarks objectAtIndex:0];

            // Create an MKPlacemark and add it to the mapView
            place = [[MKPlacemark alloc] initWithPlacemark:topResult];
            [self.mapView addAnnotation:place];
        }

        if (error) {
            NSLog(@"Error: %@", [error localizedDescription]);
        }
    }];
    NSLog(@"%@", [place description]);
    return place;
}

コードを実行すると、MKPlacemarkの場所がマップに追加されます。ただし、値をログに記録すると、NULLになります。ブロックがすぐに実行されないためかもしれませんか?したがって、NSLogが最初に実行され、次にcompletionHandlerが実行される可能性があります。ただし、コードの他の場所でその値を使用できるように、このメソッドからMKPlacemarkを返すにはどうすればよいですか?ありがとう。

4

1 に答える 1

1

「場所」を保持したい場合は、自分自身に ivar/property を作成します (自分自身が何であれ)。__block 変数として宣言します。次に、次のようにします。

self.place = [[MKPlacemark alloc] initWithPlacemark:topResult];

または、複数の場所を追跡したい場合は NSArray ivar を作成し、ブロックが実行されるたびにオブジェクトを配列に追加することもできます。

はい、あなたの NSLog(@"%@", [場所の説明]); ブロックが実行される前に実行されます。

編集:このメソッドから場所を「返す」場合は、メソッドを次のようなブロックメソッドにする必要があります。

typedef void (^SuccessBlock)(id);
typedef void (^FailureBlock)(NSError *);

- (void)placeMarkFromString:(NSString *)address withSuccess:(SuccessBlock)success andFailure:(FailureBlock)failure {

    ... //inside the enumerateObjectsUsingBlock block
    success(place);

    ...
    failure(error);

}
于 2012-05-11T19:06:45.033 に答える