直到reverseGeocode返回

我正在尝试从坐标中find用户的位置以保存到我的数据库中。

要find我正在使用reverseGeocode的位置名称。 但是,因为它是一个块的方法,我self.locationName将返回(并保存为零)到数据库中。 所以我试图find一个解决scheme的问题,并试图放在一起使用信号量以下解决scheme尝试和阻止,直到我得到一个locationName我可以保存,但应用程序只是挂起时,保存button被按下。 我是否应该以这种方式解决这个问题,还是有更好的办法?

dispatch_semaphore_t semaphore; - (void)reverseGeocode:(CLLocation *)location { CLGeocoder *geocoder = [[CLGeocoder alloc] init]; [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) { NSLog(@"Finding address"); if (error) { NSLog(@"Error %@", error.description); } else { CLPlacemark *placemark = [placemarks lastObject]; self.locationName = [NSString stringWithFormat:@"%@", ABCreateStringWithAddressDictionary(placemark.addressDictionary, NO)]; dispatch_semaphore_signal(semaphore); } }]; } -(NSString *)findLocation:(CLLocation *)startingLocation { semaphore = dispatch_semaphore_create(0); [self reverseGeocode:startingLocation]; dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); //should maybe timeout return self.locationName; } 

你正在想这一切都是错误的。 这不是asynchronous代码的工作方式。 在代码返回之前不要阻塞。 只需启动代码即可启动反向地理编码,然后完成。 现在,当反向地理编码结束时,它会回叫您,您可以使用返回的信息执行任何操作。 这是完成处理程序的完整点:它只有在反向地址parsing完成后才会运行。

只要摆脱信号量,让事情asynchronous发生。 这是一个没有辅助方法的完整示例:

 CLLocation* loc = userLocation.location; [geo reverseGeocodeLocation:loc completionHandler:^(NSArray *placemarks, NSError *error) { if (placemarks) { CLPlacemark* p = [placemarks objectAtIndex:0]; NSLog(@"%@", p.addressDictionary); // do something with address } }]; 

正如你已经被告知的那样,如果你真的想从另一个方法调用这个方法,然后再做一些事情,那么将一个块传递给这个方法,并在完成处理程序中调用这个块。 这意味着您传递的代码块将在地理编码完成时运行,这正是您想要的 – 没有信号量并且不冻结应用程序。

冻结应用程序是不好的forms,WatchDog将杀死你的应用程序,如果你这样做太久了。 只是不要这样做。