swift - 将完成处理程序与 DispatchQueue 一起使用

标签 swift concurrency grand-central-dispatch nsurlsession completionhandler

我了解到并发 DispatchQueue 允许其中的代码立即返回,因此不会阻塞调用线程。这通常用于加载大数据的后台任务。

我还了解到完成处理程序(例如,在 URLSession 中)允许处理程序中的代码在某些任务完成后执行。

我的问题是:这是否意味着并发调度队列和完成处理程序有重叠的目的?如果我已经使用了完成处理程序,就不需要用并发调度队列包装它了吗?

例如,下面是一个使用 URLSession 的耗时数据加载任务,用并发调度队列包装它是个好主意吗?

URLSession(configuration: URLSessionConfiguration.default).dataTask(with: propertiesRequest) { data, response, error in
        // print("within dataTask: data: \(data), response: \(response), error: \(error)")
        if let error = error {
            print(error)
        } else if let httpResponse = response as? HTTPURLResponse {
            if httpResponse.statusCode == 200 {
                print("success: property task request")


                do {

                    handler(responseDict, nil) // This is a function supplied by caller

                } catch let error as NSError {
                    handler(nil, error)
                }
            }
        }
    }

最佳答案

您不必将 Grand Central Dispatch (GCD) 调度队列与耗时的 URLSession 请求结合使用。

如果满足以下条件,您可能会在 dataTask 完成处理程序闭包中使用 GCD:

  1. 如果您在闭包内部做某事本身非常耗时(例如处理非常复杂的请求)并且您不想占用 URLSession 的串行操作队列用于处理其完成处理程序(和委托(delegate)方法)。这似乎不是这里的问题(例如,解析 JSON 响应通常足够快,我们不必担心这一点),但仅供引用。或者,

  2. 如果,当您完成解析 dataTask 的响应时,如果您想要更新某些模型对象或更新 UI。您想在主队列中执行这些操作。

    例如,如果您的请求返回一堆对象以显示在某个 TableView 中,您会将模型和 UI 的更新分派(dispatch)到主队列:

    DispatchQueue.main.async {
        self.objects = ...
        self.tableView.reloadData()
    }
    

但是您不必担心耗时的 URLSession 请求本身。这已经异步发生,因此您不必将其分派(dispatch)到后台队列。

关于swift - 将完成处理程序与 DispatchQueue 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46058145/

相关文章:

ios - 添加导航栏但没有后退按钮

java - 这个 IntStream 分区实现真的不是线程安全的吗?

swift - 如何在主线程中同步运行多个方法?

ios - 如何检测我的设备是否是 Swift 4 中的 iPhone X?

ios - 带有通过服务器更新的动态问题的 iPhone 问答游戏 (Parse/JSON)

java - 在事务中运行 SELECT + UPDATE 与单独使用 UPDATE 有不同的结果吗?

perl - 多少个并行进程?

ios - Block_release 在后台线程上释放 UI 对象

ios - 重新加载数据时 TableView 闪烁

swift - 是否可以制作通用的 Realm 结果对象?