【问题标题】:Wait an asynchronous callback - Objective-C等待异步回调 - Objective-C
【发布时间】:2011-05-10 22:16:43
【问题描述】:

我在使用 CLLocationManager 回调时遇到了一些问题
等待异步回调的最佳方式是什么?

这是我基本上想做的事情:

- (NSString *)getCurrentCity { [self.locationManager startUpdatingLocation]; // 等待回调中的坐标 self.geocoder = [MKReverseGeocoder alloc] initWithCoordonate:self.newCoordonate]; [self.geocoder 开始]; // 使用 MKReverse 回调等待信息 返回 self.currentCity; } // MKReverseGeocoder 和 CLLocationManager 的回调方法 - (void)locationManager:(CLLocationManager *)manager idUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { CLLocationCoordinate2D newCoordonate = newLocation.coordinate; self.currentCoordonate = &newCoordonate; } - (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark { self.currentCity = placemark.locality; }

self.currentCity 和 self.newCoordonate 是我班级的一个属性。

我尝试了一些技巧,例如线程和/或同步,但我没有设法让它在一切完成之前不返回。

最好的问候

【问题讨论】:

  • self.currentCoordonate = &newCoordonate;这让我在很多层面上都感到害怕
  • 异步回调的全部意义在于您不必等待它。

标签: objective-c multithreading callback


【解决方案1】:

每当您阻塞主线程时,您的应用程序就会变得无响应(充其量)并且会被系统抛弃(即被杀死——在最坏的情况下)。

对于异步 API,最简单的模式是将 所有 的线程或队列或用于将工作从主线程中取出的任何机制隔离到一个负责会合回根据需要主线程。

例如,查看NSFileHandle。它有一个readInBackgroundAndNotify: 方法。使用时,NSFileHandle 实例在内部创建一个线程,使用该线程读取所需的任何内容,然后使用类似performSelectorOnThread: 的东西将通知发送到调用readInBackgroundAndNotify: 的线程(通常是主线程)第一名。

通过这样做,该类的用户不必处理线程该类不会阻塞主事件循环。


顺便说一句:

{
    CLLocationCoordinate2D newCoordinate = newLocation.coordinate;
    self.currentCoordonate = &newCoordinate;
}

这是完全错误的,并且是保证崩溃或未定义行为的可靠方法。 &newCoordinate 给出了newCoordinate 的地址,但该结构在堆栈上。一旦该方法返回,该结构的内容就会被丢弃。

【讨论】:

  • 我这样做是因为我声明了一个 CLLocationCoordinate2D 的指针。所以 CLLocationCoordinate2D *newCoordinate = &newCoordinate;完美工作
  • @KL94:是的,它是一个指针,当然,您的代码被 Objective-C 的类型系统所接受。一个工作程序不仅仅是确保你的类型匹配。获取指向自动变量的指针并将其存储在实例变量中是未定义的行为——这是等待发生的错误或崩溃。问自己以找到正确解决方案的问题:为什么该实例变量是指针?如果有它需要的原因,那是什么原因?您需要围绕该约束正确设计代码。否则,不要让它成为指针。
【解决方案2】:

您无需等待它完成,而是在调用异步locationmanager:didUpdatefromLocation: 时处理更新。这就是异步编程的重点。 :)

【讨论】:

  • 我同意;实际上 。我只是想通过异步回调调用一种方法来获取一个信息。如果我能通过它同步,我想我会很好
  • 一种方法可能是编写一个包装类GPSManager 或类似的东西。它将处理CLLocationManager 的东西并公开两个属性,例如positionAvailablecurrentPosition,以便在您的其他代码中使用。
  • 我已经尝试过了,但它的同一点......如何知道我的财产是否发生了变化?它也可以异步工作。
  • 好吧,那么无论如何你都想要一个异步回调,所以没问题...?
猜你喜欢
  • 2021-06-30
  • 2014-06-20
  • 1970-01-01
  • 2018-09-22
  • 2017-06-29
  • 2019-11-15
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
相关资源
最近更新 更多