【问题标题】:A solution to track a batch of HTTP requests in swift 3.0swift 3.0中跟踪一批HTTP请求的解决方案
【发布时间】:2016-09-21 18:16:57
【问题描述】:

我正在使用在 iOS 10.0 下运行的 swift 3.0,我想编写一些在满足批处理条件时触发的代码。

for i in 0 ..< rex {
   async code, disappears and does it stuff
}

想象异步代码是 URL 请求的集合,当我循环通过它们时,它基本上是背景。现在,当“rex”请求完成后,我该如何触发更多代码?

我想过设置一个计时器来观察和检查每一秒,但这肯定不是一个好的解决方案。

我想启动另一个线程来简单地观察正在收集的数据,并在其配额已满时触发,但这确实比计时器更糟糕。

我正在考虑在每个 URL 请求的末尾包含一个测试,以查看它是否是最后一个完成的,而不是使用 NotificationCenter,但这是最佳解决方案吗?

【问题讨论】:

    标签: swift alamofire nsurl key-value-observing


    【解决方案1】:

    虽然OperationQueue(又名NSOperationQueue)在许多情况下是一个不错的选择,但它并不适合您的用例。问题是 URL 请求是异步调用的。您的NSOperation 将在您收到来自网络服务的响应之前完成。

    改用DispatchGroup

    let group = DispatchGroup()
    
    // We need to dispatch to a background queue because we have 
    // to wait for the response from the webservice
    DispatchQueue.global(qos: .utility).async {
        for i in 0 ..< rex {
            group.enter()          // signal that you are starting a new task
            URLSession.shared.dataTask(with: urls[i]) { data, response, error in
                // handle your response
                // ....
                group.leave()      // signal that you are done with the task
            }.resume()
        }
    
        group.wait()               // don't ever call wait() on the main queue
    
        // Now all requests are complete
    }
    

    【讨论】:

    • 我使用的是 alamofire 实际上不是 URLSession,并且看不到简历如何适合图片,但没关系。无论如何,这完美无缺!这是我这个月学到的最有用的一点代码,不,今年!如果可以的话,我会投票两次...
    【解决方案2】:

    所以我很确定你想要的是found here。基本上你想使用 GCD 并有一个完成闭包。这是一行代码,总是让我咯咯笑。关于主题is here 的更长帖子。

    【讨论】:

    • 感谢 Maury,您的帖子也很有用。也会尝试更好地了解这个小宝石。
    【解决方案3】:

    您正在寻找的是 NSOperationQueue(或 Swift 3 中的 OperationQueue)。这是Swift tutorial(可能有点过时)。这是 Apple 的 documentation on it——在 Swift 3 中,它们删除了所有 NS 前缀,所以它是 OperationQueue / Operation

    基本上,您应该将每个 URL 任务作为 Operation 添加到 OperationQueue,并将每个 URL 任务作为依赖项“完成”Operation,并将其添加到队列中。然后,一旦您完成了所有 URL 任务,它就会调用您的 done 操作,您可以将其设置为做任何您想做的事情。

    您可能需要继承 Operation 以便正确更新 isExecutingisFinished 属性。 This question may be of some help here

    【讨论】:

    • 谢谢shim,虽然我觉得下一条评论是对的,但是URL会报告HTTP请求返回之前执行的任务。
    • 这就是为什么你继承 Operation 并根据你的 HTTP 请求何时开始/结束来更新 isExecuting / isFinished 属性。非常典型的用例。
    • 如果您担心请求的序列化并且很可能这些是异步请求,您可以使用 OperationQueue 和 maxConcurrentOperationCount = 1,然后将异步 Web 服务调用包装在 NSBlockOperation 中并将其添加到队列中。无论您添加多少,它们一次只会执行一个。如果你也想走这条路,你也可以指定依赖操作
    猜你喜欢
    • 2017-02-19
    • 1970-01-01
    • 2012-05-03
    • 2012-03-18
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-10
    相关资源
    最近更新 更多