假设我已经创建了一个URLSessionTask实例
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
print (\(Thread.current))
}
// I start the task by
task.resume()我想了解URLSessionTask实例在默认情况下是在主线程上运行还是在后台线程中运行。所以,我打印Thread.current。
当我运行我的代码时,它打印出来:
<NSThread: 0x170273980>{number = 4, name = (null)}我的问题是:
URLSessionTask运行的是哪个线程?主线程还是后台线程?name中显示null?这是否意味着默认情况下它在后台线程中运行?(我在主线程上看到name=" main“表示print )URLSessionTask才能强制它在后台线程中运行?我之所以这样问是因为我看到了一些教程不使用GCD来运行URLSessionTask,它们只使用GCD在主线程中运行完成处理程序。发布于 2017-08-02 15:00:29
简短的回答:关键的观察是,URLSessionTask总是针对启动它的线程异步运行。除非显式指定,否则完成处理程序和/或委托方法将在后台线程上运行。因此,在启动请求时不必使用GCD,但在完成处理程序中,我们将使用GCD将任何更新UI或模型的内容分派给主队列。
你问:
URLSessionTask运行的是哪个线程?主线程还是后台线程?这里确实有两个问题:哪个线程(S) URLSession内部使用它自己的目的,以及哪个线程将运行完成处理程序和/或委托方法。
关于前一个问题,这是一个内部实现细节,在任何地方都没有文档,但是它似乎创建了自己的(背景)线程,并使用单独的run循环来处理请求。但是这些实现细节通常并不重要:我们确信请求是异步运行的(不会阻塞当前线程)。
后一个问题(在哪个线程上调用完成处理程序和委托方法)通常要重要得多。除非我们另有规定,否则URLSession会在URLSession为我们创建的串行操作队列上运行完成处理程序和委托方法。这意味着这些线程在后台线程上运行。
此规则的唯一例外是在实例化OperationQueue.main时将URLSession指定为URLSession参数,在这种情况下,URLSession显然将使用主线程来处理完成处理程序和委托方法。但是即使在这种情况下,请求也会异步运行,URLSession也不会阻塞主线程。
它运行在一个串行操作队列上。操作队列所使用的线程通常没有名称。但是您可以查看OperationQueue.current?.name来确认正在使用哪个操作队列。
URLSessionTask才能强制它在后台线程中运行?我之所以这样问是因为我看到了一些教程不使用GCD来运行URLSessionTask,它们只使用GCD在主线程中运行完成处理程序。这些教程所建议的流程是正确的。在启动请求时,不必使用GCD。它总是针对启动它的队列异步运行。唯一需要做的事情是将完成处理程序或委托方法中的相关代码分派到适当的队列中。
具体来说,由于我们通常允许URLSession在自己的串行队列上运行完成处理程序,因此我们必须将UI更新发送回主队列。有时被忽略,我们通常也会将模型更新发送回主队列(或者使用其他一些同步机制)。
https://stackoverflow.com/questions/45463996
复制相似问题