Iphone 在块内设置变量后,该变量为null

Iphone 在块内设置变量后,该变量为null,iphone,Iphone,我想我不明白在这种情况下块是如何工作的。我试图从CLGeocoder获取位置,并在块完成后保存MKPlacemark。因此,在这种方法中: - (MKPlacemark *)placeMarkFromString:(NSString *)address { CLGeocoder *geocoder = [[CLGeocoder alloc] init]; __block MKPlacemark *place; [geocoder geocodeAddressString:

我想我不明白在这种情况下块是如何工作的。我试图从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,以便在代码的其他地方使用该值?谢谢。

如果您想保留“位置”,请在self(无论self是什么)上为其创建ivar/属性。将其声明为_块变量。然后做:

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);

}

您的
place
变量可能为nil,因为没有返回placemarks,因此您永远不会输入if语句。您是否在if语句中设置了断点并确保它执行?为什么我需要为它设置一个ivar,而不仅仅是让方法返回它?因为placeMarkFromString是一个异步方法。如果要从方法“返回”位置,请参见上面的编辑。