使用reverseGeocodeLocation设置地址字符串并从方法

问题描述:

设置地址字符串我尝试本地化开始和结束点到地址字符串,以便我可以将它存储到NSUserDefaults。问题是该方法继续执行,并没有设置我的变量。使用reverseGeocodeLocation设置地址字符串并从方法

NSLog(@"Begin"); 

__block NSString *returnAddress = @""; 

[self.geoCoder reverseGeocodeLocation:self.locManager.location completionHandler:^(NSArray *placemarks, NSError *error) { 
    if(error){ 
     NSLog(@"%@", [error localizedDescription]); 
    } 

    CLPlacemark *placemark = [placemarks lastObject]; 

    startAddressString = [NSString stringWithFormat:@"%@ %@\n%@ %@\n%@\n%@", 
          placemark.subThoroughfare, placemark.thoroughfare, 
          placemark.postalCode, placemark.locality, 
          placemark.administrativeArea, 
          placemark.country]; 
    returnAddress = startAddressString; 

    //[self.view setUserInteractionEnabled:YES]; 
}]; 
NSLog(returnAddress); 

NSLog(@"Einde"); 

这是我的应用程序调试器显示:

开始
einde

举例来说,如果我的位置的地址是: “主街32 CITY”。那么我想看到的是以下内容:

开始
主街32,CITY
Einde

的问题是,我的代码不会等待我的CLGeocoder来完成,所以我变量returnAddress在返回时未设置,并且为空。

有谁知道如何解决这个问题?

因为reverseGeocodeLocation有一个完成块,当它执行到达时它会被切换到另一个线程 - 但主线程上的执行仍然会继续到下一个操作,即NSLog(returnAddress)。此时,returnAddress尚未设置,因为reverseGeocodeLocation只是已交给另一个线程。

使用完成块时,您必须开始考虑异步工作。

考虑将reverseGeocodeLocation作为方法中的最后一个操作,然后使用完成块中的其余逻辑调用新方法。这将确保在returnAddress的值为0之前逻辑不会执行。

- (void)someMethodYouCall 
{ 
    NSLog(@"Begin"); 
    __block NSString *returnAddress = @""; 

    [self.geoCoder reverseGeocodeLocation:self.locManager.location completionHandler:^(NSArray *placemarks, NSError *error) { 
     if(error){ 
      NSLog(@"%@", [error localizedDescription]); 
     } 

     CLPlacemark *placemark = [placemarks lastObject]; 

     startAddressString = [NSString stringWithFormat:@"%@ %@\n%@ %@\n%@\n%@", 
           placemark.subThoroughfare, placemark.thoroughfare, 
           placemark.postalCode, placemark.locality, 
           placemark.administrativeArea, 
           placemark.country]; 
     returnAddress = startAddressString; 

     //[self.view setUserInteractionEnabled:YES]; 

     NSLog(returnAddress); 
     NSLog(@"Einde"); 

     // call a method to execute the rest of the logic 
     [self remainderOfMethodHereUsingReturnAddress:returnAddress]; 
    }]; 
// make sure you don't perform any operations after reverseGeocodeLocation. 
// this will ensure that nothing else will be executed in this thread, and that the 
// sequence of operations now follows through the completion block. 
} 

- (void)remainderOfMethodHereUsingReturnAddress:(NSString*)returnAddress { 
    // do things with returnAddress. 
} 

或者您可以使用NSNotificationCenter发送通知时reverseGeocodeLocation完成。您可以在需要的任何地方订阅这些通知,并从那里完成逻辑。替换为[self remainderOfMethodHereWithReturnAddress:returnAddress];

NSDictionary *infoToBeSentInNotification = [NSDictionary dictionaryWithObject:returnAddress forKey:@"returnAddress"]; 

[[NSNotificationCenter defaultCenter] 
    postNotificationName:@"NameOfNotificationHere" 
    object:self 
    userInfo: infoToBeSentInNotification]; 
    }]; 

Here's使用NSNotificationCenter的一个例子。

+0

是的,我知道,但在我的情况下,我需要在完成块外使用该变量。因为我在块之外还有其他一些逻辑,所以我不能放在块内。你知道一个办法吗?你有没有链接或样本我的异步线程?谢谢 – Wesley

+0

我已经用一些方法更新了答案,您可以用您需要的返回地址执行剩余的逻辑。 –

+0

太棒了,我已经想通了!谢谢。 – Wesley