2012-05-11 44 views
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,以便在代碼中的其他位置使用該值?謝謝。

+0

你'place'變量可以是零返回的地標使您永遠不會輸入if語句。你有沒有在if語句中設置斷點並確保它執行? –

回答

1

如果你想保留「地點」,爲自己創建一個ivar /財產(無論是自我)。將其聲明爲__block變量。然後執行:

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

或者你可以創建一個NSArray ivar,如果你想跟蹤多個位置,然後每次執行該塊時將該對象添加到數組中。

是的,你的NSLog(@「%@」,[place description]);將在塊執行之前運行。

編輯:如果您想從這種方法「迴歸」的地方,你就需要讓你的方法塊的方法是這樣的:因爲沒有

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

} 
+0

爲什麼我需要一個ivar,而不是僅僅讓這個方法返回呢? – Crystal

+1

因爲placeMarkFromString是一個異步方法。如果您想從方法中「返回」地方,請參閱上面的編輯。 – Joel