【问题标题】:Waiting for multiple async web calls then performing action on their results等待多个异步网络调用,然后对其结果执行操作
【发布时间】:2013-03-15 14:21:11
【问题描述】:

处理多个异步 Web 调用的最佳做法是什么。

塞纳里奥:

我正在从一个 Web 服务的 JSON 提要中获取大量地址列表,同时查询 CLGeocoder 以从地址字符串中进行纬度/经度查找。然后,一旦我有了这两条信息,我就想执行一个操作。

不将所有方法耦合在一个链接链中的最佳方法是什么?

【问题讨论】:

  • 这是个棘手的问题。我建议只开始第一个异步,完成后启动第二个,当第二个完成时执行您的操作。

标签: iphone ios objective-c asynchronous


【解决方案1】:

等待同步任务:

我建议创建一个新的NSOperationQueue,将其配置为拥有尽可能多的线程,然后在该线程上启动操作。要等待它们完成,只需调用waitUntilAllOperationsAreFinished 方法即可。

例如:

NSOperationQueue* operationQueue = [[NSOperationQueue alloc] init];

// Add your tasks here

[operationQueue addOperationWithBlock:^{
    // Long running task
}];

[operationQueue waitUntilAllOperationsAreFinished];

注意不要阻塞主线程,否则您的应用程序在加载时会变得无响应。

如果您需要比这更复杂的东西,您可以使用较低级别的 API dispatch_group_t 对线程进行分组并等待它们。请查看this response 以获得更深入的解释。

等待已经异步的任务:

有时上述方法还不够,可能是因为您需要等待已经异步的任务(例如启用 GPS 或等待某些外部事件)。在这些情况下,您可以使用信号量。您必须非常小心错误处理和信号量,否则您可能会永远阻塞线程。

dispatch_semaphore_t sema = dispatch_semaphore_create(0);

[object performLongOperationAndDo:^{
    dispatch_semaphore_signal(sema);
}];

dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
dispatch_release(sema);

更多info about Obj-C semaphores.

除非必要,我会坚持NSOperationQueue

【讨论】:

  • 感谢您的回答。
  • 如何让 NSOperationQueue 等待完成块? CLGeocoder 使用完成处理程序。
  • 快速尝试了 dispatch_group,同样的事情。它将等待我的方法完成,但不会等待它们中的任何块。
  • 非常感谢您的回答。
【解决方案2】:

也许你会发现这很有用:Reactive Cocoa

对于您的问题类型,这是一个非常优雅的解决方案。该框架的学习曲线非常陡峭。

【讨论】:

    猜你喜欢
    • 2018-03-03
    • 2012-02-25
    • 1970-01-01
    • 1970-01-01
    • 2020-01-25
    • 1970-01-01
    • 2015-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多