查看URLSession.dataTask
的{{1}},很明显这个函数是异步调用的,但是没有提到completionHandler是否返回主线程,调用的线程它或者保留在执行dataTaskOperation的线程上。
这里有一个普遍的约定吗?
let task = URLSession.shared().dataTask(with: request) {
//What Thread are we on here?
}
答案 0 :(得分:3)
来自completionHandler
的{{1}}参数的文档:
此处理程序在委托队列上执行。
所以下一个问题是,委托队列是什么?这一切都取决于URLSession dataTask
的设置方式。您正在使用URLSession
会话设置shared
委托队列。 nil
方法的queue
参数的文档说明:
如果为nil,则会话创建一个串行操作队列,用于执行所有委托方法调用和完成处理程序调用。
因此,您发布的代码会导致在后台串行队列上调用完成处理程序。
答案 1 :(得分:1)
<强> URLSession 强>
在文档中说......
此处理程序在委托队列上执行。
查看委托队列......
在此队列上执行与会话相关的所有委托方法调用和完成处理程序。会话对象保留对此队列的强引用,直到您的应用程序退出或取消分配会话对象。如果您没有使会话无效,那么您的应用程序会在内存泄漏之前泄漏内存。
请注意
此队列必须在创建对象时设置,并且不能更改。
查看init方法......
实际上并没有说明使用什么类型的队列......
嗯...
正如@rmaddy所指出的那样,会话会创建一个串行队列,以便在后台线程上运行。
<强>会展强>
至于公约......实际上没有。
如果您自己编写有需要考虑的事项......完成可能会更新UI吗?完成是否会进行大量的数据处理......您可以从那里做出决定。
答案 2 :(得分:0)
正如@rmaddy 所建议的,它确实在单独的队列中运行。它似乎被标记为:com.apple.NSURLSession-delegate
实验:
import Foundation
func currentQueueName() -> String? {
String(cString: __dispatch_queue_get_label(nil), encoding: .utf8)
}
let dispatchQueue = DispatchQueue(label: "my-queue", qos: .userInteractive)
dispatchQueue.async {
print(currentQueueName()!) // output: my-queue
URLSession.shared.dataTask(with: URL(string:"https://www.google.com")!) { _,_,_ in
print(currentQueueName()!) // output: com.apple.NSURLSession-delegate
}.resume()
}