URLSessionTask是如何运行的 [英] How does URLSessionTask run
问题描述
假设我创建了一个 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)}
我的问题是:
-
URLSessionTask
正在运行的线程默认?主线程或后台线程?
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.
你问:
- 哪个线程
URLSessionTask
默认运行?主线程或后台线程?
- 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.
- 为什么当前线程在线程名称中显示为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.
- 一般来说,是否有必要使用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 runURLSessionTask
, 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屋!