假设我创建了一个实例URLSessionTask
:
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
print (\(Thread.current))
}
// I start the task by
task.resume()
我想了解是否URLSessionTask
实例正在运行main默认情况下或在背景线。所以,我打印Thread.current
.
当我运行我的代码时,它打印出:
<NSThread: 0x170273980>{number = 4, name = (null)}
我的问题是:
哪个线程URLSessionTask
默认运行吗?主线程还是后台线程?
为什么当前线程在线程中显示为空name
?这是否意味着它默认在后台线程中运行? (我看到 name="main" 为print
在主线程上)
一般来说,是否需要运行URLSessionTask
是否使用GCD强制它在后台线程中运行?我问这个是因为我看到一些教程不使用GCD来运行URLSessionTask
,他们只使用 GCD 在主线程中运行完成处理程序。
简短回答:关键的观察是URLSessionTask
始终相对于您启动它的线程异步运行。除非您明确指定,否则完成处理程序和/或委托方法将在后台线程上运行。因此,在发起请求时不必使用 GCD,但在完成处理程序中,我们将使用 GCD 将更新 UI 或模型的任何内容分派到主队列。
你问:
- 哪个线程
URLSessionTask
默认运行吗?主线程还是后台线程?
实际上有两个问题:哪个线程URLSession
在内部用于其自身目的以及将运行完成处理程序和/或委托方法的线程。
关于前一个问题,这是一个内部实现细节,没有在任何地方记录,但它似乎创建了自己的(后台)线程,并带有单独的运行循环来处理请求。但这些实现细节通常并不重要:我们确信请求是异步运行的(不会阻塞当前线程)。
后一个问题,即在哪个线程上调用完成处理程序和委托方法,通常更为重要。除非我们另有说明,URLSession
在串行操作队列上运行完成处理程序和委托方法URLSession
为我们创造的。这意味着它们在后台线程上运行。
此规则的唯一例外是如果您指定OperationQueue.main
as the queue
实例化时的参数URLSession
,在这种情况下,它显然会使用主线程来完成处理程序和委托方法。但即使在这种情况下,请求也会异步运行URLSession
不会阻塞主线程。
- 为什么当前线程的线程名称显示为 null?这是否意味着它默认在后台线程中运行? (我看到 name="main" 在主线程上打印)
它在串行操作队列上运行。操作队列线程使用的线程通常没有名称。但你可以看看OperationQueue.current?.name
确认正在使用哪个操作队列。
- 一般来说,是否需要运行
URLSessionTask
是否使用GCD强制它在后台线程中运行?我问这个是因为我看到一些教程不使用GCD来运行URLSessionTask
,他们只使用 GCD 在主线程中运行完成处理程序。
这些教程建议的流程是正确的。发起请求时不必使用 GCD。它始终相对于您启动它的队列异步运行。您唯一需要做的就是将完成处理程序或委托方法中的相关代码分派到适当的队列。
具体来说,由于我们通常让URLSession
在其自己的串行队列上运行完成处理程序,因此我们必须将 UI 更新分派回主队列。有时会被忽视,我们通常也会将模型更新分派回主队列(或使用其他一些同步机制)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)