首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >URLSessionTask是如何运行的

问URLSessionTask是如何运行的
EN

Stack Overflow用户
提问于 2017-08-02 14:43:28
回答 1查看 2.8K关注 0票数 9

假设我已经创建了一个URLSessionTask实例

代码语言:javascript
复制
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in 
   print (\(Thread.current))
}
// I start the task by
task.resume()

我想了解URLSessionTask实例在默认情况下是在主线程上运行还是在后台线程中运行。所以,我打印Thread.current。

当我运行我的代码时,它打印出来:

代码语言:javascript
复制
<NSThread: 0x170273980>{number = 4, name = (null)}

我的问题是:

  1. 默认情况下,URLSessionTask运行的是哪个线程?主线程还是后台线程?
  2. 为什么当前线程在线程name中显示null?这是否意味着默认情况下它在后台线程中运行?(我在主线程上看到name=" main“表示print )
  3. 通常,是否需要使用GCD运行URLSessionTask才能强制它在后台线程中运行?我之所以这样问是因为我看到了一些教程不使用GCD来运行URLSessionTask,它们只使用GCD在主线程中运行完成处理程序。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-02 15:00:29

简短的回答:关键的观察是,URLSessionTask总是针对启动它的线程异步运行。除非显式指定,否则完成处理程序和/或委托方法将在后台线程上运行。因此,在启动请求时不必使用GCD,但在完成处理程序中,我们将使用GCD将任何更新UI或模型的内容分派给主队列。

你问:

  1. 默认情况下,URLSessionTask运行的是哪个线程?主线程还是后台线程?

这里确实有两个问题:哪个线程(S) URLSession内部使用它自己的目的,以及哪个线程将运行完成处理程序和/或委托方法。

关于前一个问题,这是一个内部实现细节,在任何地方都没有文档,但是它似乎创建了自己的(背景)线程,并使用单独的run循环来处理请求。但是这些实现细节通常并不重要:我们确信请求是异步运行的(不会阻塞当前线程)。

后一个问题(在哪个线程上调用完成处理程序和委托方法)通常要重要得多。除非我们另有规定,否则URLSession会在URLSession为我们创建的串行操作队列上运行完成处理程序和委托方法。这意味着这些线程在后台线程上运行。

此规则的唯一例外是在实例化OperationQueue.main时将URLSession指定为URLSession参数,在这种情况下,URLSession显然将使用主线程来处理完成处理程序和委托方法。但是即使在这种情况下,请求也会异步运行,URLSession也不会阻塞主线程。

  1. 为什么当前线程在线程名中显示为null?这是否意味着默认情况下它在后台线程中运行?(我在主线程上看到name=" main“表示打印)

它运行在一个串行操作队列上。操作队列所使用的线程通常没有名称。但是您可以查看OperationQueue.current?.name来确认正在使用哪个操作队列。

  1. 通常,是否需要使用GCD运行URLSessionTask才能强制它在后台线程中运行?我之所以这样问是因为我看到了一些教程不使用GCD来运行URLSessionTask,它们只使用GCD在主线程中运行完成处理程序。

这些教程所建议的流程是正确的。在启动请求时,不必使用GCD。它总是针对启动它的队列异步运行。唯一需要做的事情是将完成处理程序或委托方法中的相关代码分派到适当的队列中。

具体来说,由于我们通常允许URLSession在自己的串行队列上运行完成处理程序,因此我们必须将UI更新发送回主队列。有时被忽略,我们通常也会将模型更新发送回主队列(或者使用其他一些同步机制)。

票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45463996

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档