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

Posted

技术标签:

【中文标题】使用 reverseGeocodeLocation: 设置地址字符串并从方法返回【英文标题】:Set address string with reverseGeocodeLocation: and return from method 【发布时间】:2013-01-15 20:41:55 【问题描述】:

我正在尝试将起点和终点本地化为地址字符串,以便将其存储到NSUserDefaults。问题是该方法继续执行并且没有设置我的变量。

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

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

开始 恩德

例如,如果我所在位置的地址是:“Mainstreet 32​​, CITY”。那么我想看到的是以下内容:

开始 城市大街 32 号 爱因德

问题是我的代码没有等到我的CLGeocoder完成,所以我的变量returnAddress在返回的时候没有设置,是空的。

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

【问题讨论】:

【参考方案1】:

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

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

考虑将reverseGeocodeLocation 作为方法中的最后一个操作,然后在完成块内调用具有剩余逻辑的新方法。这将确保在您获得 returnAddress 的值之前不会执行逻辑。

- (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 的示例。

【讨论】:

是的,我知道,但就我而言,我需要在完成块之外使用该变量。因为我在块之外还有一些其他逻辑,所以我不能放在块内。你知道这样做的方法吗?你有异步线程的链接或示例吗?谢谢 我已经用一些方法更新了答案,你可以用你需要的返回地址来执行你的逻辑的其余部分。 太棒了,我现在明白了!谢谢。

以上是关于使用 reverseGeocodeLocation: 设置地址字符串并从方法返回的主要内容,如果未能解决你的问题,请参考以下文章

reverseGeocodeLocation 存储为 NSString 产生错误

在 iOS 中强制使用 reverseGeocodeLocation 的语言环境

从 reverseGeocodeLocation 仅返回英文地址

Swift 中的 CLGeocoder - 使用 reverseGeocodeLocation 时无法返回字符串

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

如何本地化来自 reverseGeocodeLocation 的地址结果?