I was wondering what happens if I call something asynchronously in main queue from viewDidLoad method. A little experiment showed me these results:
This code:
override func viewDidLoad() {
super.viewDidLoad()
firstSelector()
DispatchQueue.main.async {
self.secondSelector()
}
for i in 1...10 {
print(i)
}
thirdSelector()
}
func firstSelector() {
print("First selector fired")
}
func secondSelector() {
print("Second selector fired")
}
func thirdSelector() {
print("Third selector fired")
}
Gives these prints:
First selector fired
1
2
3
4
5
6
7
8
9
10
Third selector fired
Second selector fired
So the last one method that was called is secondSelector. I think this is because main queue is serial and when I call asynchronously some method (secondSelector in this case) it returns immediately and waits until all other methods will be completed. After queue is free of tasks it completes method that I called asynchronously. Am I right in my thoughts?
To summarize, DispatchQueue. async allows you to schedule work to be done using a closure without blocking anything that's ongoing. In most cases where you need to dispatch to a dispatch queue you'll want to use async .
You might call this from viewDidLoad , which means it will execute in the main thread. But you might also be getting the data from iCloud or Firebase, or synchronizing it with other databases and operations. In this case, User. swift loads data and posts a notification that the user changed, and ViewController.
DispatchQueue.main is an instance of DispatchQueue . All dispatch queues can schedule their work to be executed sync or async .
The main thread is the one that starts our program, and it's also the one where all our UI work must happen. However, there is also a main queue, and although sometimes we use the terms “main thread” and “main queue” interchangeably, they aren't quite the same thing.
I used to ask a similar question. Let me quote the important part of the answer I got:
"Because the default runloop on the main thread has the special behaviour that, when run, it also processes for the main dispatch queue..."
When you do dispatch_async
to a main thread, your block { self.secondSelector() }
gets scheduled to a main run loop. Since viewDidLoad
method is already being executed by the main run loop, your dispatched block with be processed after viewDidLoad
and all other (possible) blocks or methods that were scheduled before your block will be executed.
Keep in mind that your question is about behaviour of dispatch_async
when you dispatch to the main queue and main run loop from the main thread. viewDidLoad
has nothing to do with it - the only thing where it is relevant here, is that UIViewController
's lifecycle methods like viewDidLoad
, viewWillAppear
etc are all run on the main thread (processed by a main run loop). You will see the same behaviour with any method other than viewDidLoad
given this method is run on a main thread. If you call dispatch_async from other thread you might be surprised by different results because in that case you will have two threads working at the same time (your other thread and a main thread to which you dispatched).
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