Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 将完成处理程序与DispatchQueue一起使用_Swift_Concurrency_Grand Central Dispatch_Nsurlsession_Completionhandler - Fatal编程技术网

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

Swift 将完成处理程序与DispatchQueue一起使用,swift,concurrency,grand-central-dispatch,nsurlsession,completionhandler,Swift,Concurrency,Grand Central Dispatch,Nsurlsession,Completionhandler,我了解到并发DispatchQueue允许其中的代码立即返回,因此不会阻塞调用线程。这通常用于加载大数据的后台任务 我还了解到,完成处理程序(例如,在URLSession中)允许在某些任务完成后执行处理程序中的代码 我的问题是:这是否意味着并发调度队列和完成处理程序有重叠的用途?如果我已经使用了完成处理程序,就没有必要用并发调度队列包装它了 URLSession(configuration: URLSessionConfiguration.default).dataTask(with: prop

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

我还了解到,完成处理程序(例如,在
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)
                }
            }
        }
    }
例如,下面是一个使用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)
                }
            }
        }
    }

DispatchQueue
和完成处理程序不重叠,而是可以用作处理队列的无缝解决方案。
URLSession
中的数据加载任务已经是异步的,因此不需要包装在
DispatchQueue

DispatchQueue
-将任务分配给特定线程以获得更好的性能(全局队列)/用户体验(主队列)

完成处理程序-保证任务完成后某些代码将运行。但是,除非另有明确说明,否则将在当前线程上执行


例如,调用使用
DispatchQueue.global.async
的方法A将在全局队列上对任务进行排队,从而将主队列释放出来,用于更重要的(UI)任务。过了一段时间,任务就完成了,通常我们会想对数据做点什么。如果它与用户界面相关,我们肯定希望调用
DispatchQueue.main.async
以使用信息更新屏幕,或者如果它很简单,则无需进行调用,普通代码就足够了。

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

在以下情况下,您可以在
dataTask
完成处理程序闭包中使用GCD:

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

  • 如果,当您完成对
    dataTask
    的响应的分析时,如果您想更新某个模型对象或更新UI。您希望在主队列上执行这些操作

    例如,如果您的请求返回一组要在某个tableview中显示的对象,那么您应该将模型和UI的更新分派到主队列:

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

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

    不相关,如果
    error
    不是nil或者状态代码不是200,我会确保您调用完成处理程序。您的来电者无疑想知道请求何时完成,是否成功。@Rob我同意。将在我的项目中采用此方法