我尝试将起点和终点本地化为地址字符串,以便将其存储到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”。那么我想看到的是:
开始
Mainstreet 32,CITY
艾恩德
问题是我的代码没有等待我的CLGeocoder
完成,所以我的变量returnAddress
在返回时没有设置,并且它是空的。
有谁知道如何解决这个问题?
答案 0 :(得分:5)
因为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的一个例子。