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



我尝试将起点和终点定位到地址字符串,以便我可以将其存储到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");

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


开始einde

例如,如果我所在位置的地址是:"Mainstreet 32, CITY"。那么我想看到的是:


开始主街32号,城市
Einde

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

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

因为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];
    }];

下面是一个使用NSNotificationCenter的例子

最新更新