Say I have created an instance of URLSessionTask
:
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
print (\(Thread.current))
}
// I start the task by
task.resume()
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)}
My questions are:
which thread the URLSessionTask
is running by default? Main thread or background thread?
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)
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.
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.
You asked:
- Which thread the
URLSessionTask
is running by default? Main thread or background thread?
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).
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.
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.
- 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)
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.
- 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.
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With