5

我有一个可以拥有多个用户帐户的应用程序。我需要在后台更新所有这些。问题是:

  • 时间有限(约 30 秒,但请求可能需要更长的时间)
  • 所有请求都是异步的

我应该什么时候调用完成处理程序?

4

2 回答 2

7

中央调度组基本上就是为了解决这个问题。来自 Apple关于该主题的文档:

调度组是一种监视一组块对象是否完成的方法。(您可以根据需要同步或异步监视块。)组为依赖于其他任务完成的代码提供了有用的同步机制。有关使用组的更多信息,请参阅等待队列任务组。

有两种方法可以使用组来监控任务组。第一种是使用异步回调,另一种是阻塞当前队列,直到所有分组的任务都完成。无论哪种方式,设置都是相同的。

我将通过一个快速示例来帮助您入门(我将使用 Swift 进行回答,但同样的方法在 Objective-C 中也可以实现 1-1)。首先,定义您的组:

let group = dispatch_group_create()

每个要完成的异步任务输入一次组:

dispatch_group_enter(group)
dispatch_group_enter(group)

运行您的异步任务,当您想将每个任务标记为已完成时,请调用dispatch_group_leave

firstAsyncTask {
    dispatch_group_leave(group)
}

secondAsyncTask {
    dispatch_group_leave(group)
}

如上所述,当组中的所有任务都完成后,您可以在当前队列上等待(这将阻塞线程)或指定一个要异步调用的块。

等待

dispatch_group_wait(group, 30 * NSEC_PER_SEC)

这将在当前线程上停止执行,直到所有组任务都完成,或者经过 30 秒(以较早者为准)。

如果您想取消任何时间限制:

dispatch_group_wait(group, DISPATCH_TIME_FOREVER)

异步

这个有点简单,只是因为它并没有太多的东西。您指定一个块来调用您的块作为您的第二个参数。完成所有组的任务后,将调用此块:

dispatch_group_notify(group, dispatch_get_main_queue()) {
    // Code goes here.
}
于 2016-04-14T17:31:12.677 回答
3

我最近遇到了类似的情况,并在这里发布了一个问题。

诀窍是启动所有请求(异步)并让它们中的每一个执行一个回调函数,检查它是否是最后一个请求或是否仍有请求未决。

它确实是最后一个请求,那么回调应该执行最终的完成处理程序。

源代码可以直接从我对这个问题的回答复制到游乐场:

在 Swift 中传递和存储闭包/回调

于 2015-04-05T15:24:39.127 回答