阻止,直到reverseGeocode返回 [英] block until reverseGeocode has returned

查看:61
本文介绍了阻止,直到reverseGeocode返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to find a user's location from a coordinate to save into my database.

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

To find the location name I am using reverseGeocode. However since it is a block method my self.locationName will return (and save as nil) into the database. So I have tried to find a solution to the problem, and tried to put together the following solution using semaphores to try and block until I get a locationName I can save, but the app just hangs when the save button is pressed. Should I even be going about this problem in this way or is there a better way?

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

推荐答案

您正在考虑所有这些错误.异步代码不是这样工作的.请执行 NOT 阻止,直到代码返回.只需启动代码即可启动反向地址解析,然后完成.现在,当反向地址解析结束时,它将回叫您,您可以使用返回的信息来做任何您想做的事情.这就是完成处理程序的全部要点:直到反向地理编码完成后,它才能运行.

You are thinking about this all wrong. That is not how asynchronous code works. Do NOT block until the code returns. Just launch the code to start the reverse geocode, and finish up. Now when the reverse geocode finishes, it calls you back and you can do whatever you want with the returned info. That is the whole point of the completion handler: it doesn't run until the reverse geocode has completed.

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

Just get rid of the semaphores and let things happen asynchronously. Here is a complete example without the secondary method:

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

正如您已经被告知的,如果您真的想从另一个方法中调用它,然后做进一步的操作,则将一个块传递给该方法,然后在完成处理程序中调用该块.这意味着您传递的代码块是在地理编码完成后将要运行的代码,而这正是您想要的-无需信号量,也无需冻结应用程序.

As you've already been told, if you really want to call this from another method and then do something further, then pass a block to this method and call the block inside the completion handler. That means the block you passed is code that will run when the geocoding has completed, which is exactly what you want - without semaphores and without freezing the app.

冻结应用程序是错误的形式,如果您执行时间太长,WatchDog会杀死您的应用程序.只是不要这样做.

Freezing the app is bad form and the WatchDog will kill your app dead if you do it for too long. Just don't do it.

这篇关于阻止,直到reverseGeocode返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆