阻止直到reverseGeocode返回

时间:2014-02-27 19:59:42

标签: ios objective-c geocode

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

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

 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;
}

1 个答案:

答案 0 :(得分:3)

你正在考虑这一切都错了。这不是异步代码的工作原理。在代码返回之前, NOT 阻止。只需启动代码即可启动反向地理编码,然后完成。现在,当反向地理编码完成时,它会回叫您,您可以使用返回的信息执行任何操作。这是完成处理程序的重点:它在反向地理编码完成之前不会运行。

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

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

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

冻结应用程序是不好的形式,如果你长时间执行它,WatchDog会杀死你的应用程序死机。只是不要这样做。