【问题标题】:iOS - Concatenating asynchronous block-based operationsiOS - 连接基于块的异步操作
【发布时间】:2016-10-30 21:09:12
【问题描述】:

您将如何执行 N 个异步操作,例如网络调用、使用完成块操作和没有委托/通知?

给定 N 个这样的方法:

- (void)methodNWithCompletion:(void (^)(Result *))completion {
    Operation *operation = [Operation new];

    // ...
    // Asynchronous operation performed here
    // ...

    return;
}

一个简单的解决方案是在前一个的完成块中调用每个操作:

[self method1WithCompletion:^(Result *result) {
    // ...
    [self method2WithCompletion:^(Result *result) {
        // ...
        [self method3WithCompletion:^(Result *result) {
            // ...
            [self method4WithCompletion:^(Result *result) {
                NSLog(@"All done");
            }
        }
    }
}

但我正在寻找更优雅和可重用的解决方案,更易于编写和维护(没有很多缩进块)。

非常感谢, 丹

【问题讨论】:

  • 如果问题是“我怎么知道他们什么时候完成”,你通常会使用dispatch_group。所以,在每次异步调用之前进入组,在异步调用的完成处理程序中退出组,然后配置一个dispatch_group_notify在所有异步调用完成时执行。例如,stackoverflow.com/a/29716069/1271826stackoverflow.com/a/34532865/1271826

标签: ios objective-c asynchronous objective-c-blocks


【解决方案1】:

这一切都取决于你想做什么。许多强大的复杂工具可供您使用。你可以使用这样的东西:

  • 串行队列(如果您希望完成块按顺序运行)

  • 并发队列(如果您不关心完成块是同时执行还是按什么顺序执行)

  • 调度组(如果有事情要在所有完成块完成后才做)

  • Operation 和 OperationQueue(如果您想建立网络操作必须发生的依赖顺序 - 尤其是有关此主题的精彩 WWDC 2015 视频)

【讨论】:

  • 我需要完成块以给定的顺序执行,并且在所有块都结束后执行一些代码。我试图编写一个没有 Operation/OperationQueue 的解决方案,以保持代码非常简单。
  • 然后,阅读我在回答中所说的内容,您将使用串行队列和调度组。在我看来,Operation 更具表现力,可以更优雅地处理意外情况,但如果您使用完成块而不是委托方法,则可以在没有它的情况下进行管理。
  • 是的,我一定会看看这种方法,谢谢!
  • @DAN - “我需要按给定顺序执行完成块......” - 你确定吗?您是否绝对需要使用其中一个的结果来启动下一个?如果要求它们以特定顺序执行,您会付出巨大的性能损失。如果你必须这样做,那就这样吧,但这意味着更广泛的设计问题。
  • 这个问题已经被问过很多次了,所以我不打算就这个话题发表另一个答案。我的意思是 Dan 问“我有一堆带有完成处理程序的异步方法”,我只是想确保他知道他不能只是将这些添加到串行队列中并期望它能够工作。我建议运营或承诺/未来。或者只是做一些简单的事情,比如只在前一个的完成处理程序中启动一个请求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 2017-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多