URLSessionTask是如何运行的 [英] How does URLSessionTask run

查看:192
本文介绍了URLSessionTask是如何运行的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我创建了一个 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

I want to understand whether the URLSessionTask instance is running on main thread by default or in background thread. So, I print the Thread.current .

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

When I run my code, it print out:

<NSThread: 0x170273980>{number = 4, name = (null)}

我的问题是:


  1. URLSessionTask 正在运行的线程默认?主线程或后台线程?

  1. which thread the URLSessionTask is running by default? Main thread or background thread?

为什么当前线程在线程 name 中显示为null?这是否意味着它默认在后台线程中运行? (我在主线程上看到 print 的name =main)

Why current thread shows null in thread name? Does it mean it is running in background thread by default? (I see name="main" for print on main thread)

一般来说,是吗?使用GCD运行 URLSessionTask 是否有必要强制它在后台线程中运行?我问这个是因为我看到一些教程不使用GCD来运行 URLSessionTask ,他们只使用GCD在主线程中运行完成处理程序。

In general, is it necessary to run URLSessionTask with GCD in order to force it run in background thread or not? I am asking this because I saw some tutorials doesn't use GCD to run URLSessionTask, they only use GCD to run completion handler in main thread.


推荐答案

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

Short answer: The key observation is that the URLSessionTask always runs asynchronously with respect to the thread that you started it. And unless you explicitly specify otherwise, the completion handlers and/or delegate methods will run on a background thread. So, you don't have to use GCD when initiating the request, but in the completion handler we will use GCD to dispatch anything that updates the UI or model to the main queue.

你问:



  1. 哪个线程 URLSessionTask 默认运行?主线程或后台线程?

  1. Which thread the URLSessionTask is running by default? Main thread or background thread?


那里有两个问题:哪个线程 URLSession 内部用于其自身目的,以及将运行完成处理程序和/或委托方法的线程。

There are really two questions there: Which thread(s) URLSession uses internally for its own purposes and which thread the completion handler and/or delegate methods will be run.

在前一个问题上,这是一个内部实现细节,未在任何地方记录,但它似乎创建了自己的(后台)线程,其中有一个单独的运行循环来处理要求。但是这些实现细节通常并不重要:我们确信请求是异步运行的(不会阻塞当前线程)。

On the former question, this is an internal implementation detail that is not documented anywhere, but it appears to create its own (background) thread with a separate run loop to process requests. But these implementation details generally don't really matter: We're assured is that the request runs asynchronously (does not block the current thread).

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

The latter question, on which thread the completion handlers and delegate methods are called, is generally far more important. Unless we specify otherwise, URLSession runs completion handlers and delegate methods on serial operation queue that URLSession created for us. That means that these run on a background thread.

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

The only exception to this rule is if you specified OperationQueue.main as the queue parameter when instantiating a URLSession, in which case it would obviously use the main thread for the completion handlers and delegate methods. But even in this case, the request runs asynchronously and URLSession will not block the main thread.



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


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

It's running on a serial operation queue. The threads used by operation queues threads don't generally have names. But you can look at OperationQueue.current?.name to confirm which operation queue is being used.



  1. 一般来说,是否有必要使用GCD运行 URLSessionTask 以强制它在后台线程中运行或不?我问这个是因为我看到一些教程没有使用GCD来运行 URLSessionTask ,他们只使用GCD在主线程中运行完成处理程序。

  1. In general, is it necessary to run URLSessionTask with GCD in order to force it run in background thread or not? I am asking this because I saw some tutorials doesn't use GCD to run URLSessionTask, they only use GCD to run completion handler in main thread.


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

The flow suggested by those tutorials is correct. You do not have to use GCD when initiating the request. It always runs asynchronously with respect to the queue from which you started it. The only thing you need to do is to dispatch relevant code within the completion handler or delegate method to the appropriate queue.

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

Specifically, since we generally let URLSession run completion handlers on its own serial queue, we therefore have to dispatch UI updates back to the main queue. Sometimes overlooked, we also generally dispatch model updates back to the main queue, too (or use some other synchronization mechanism).

这篇关于URLSessionTask是如何运行的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆