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 .
Remember to always dispatch your queue to the main queue asynchronously using DispatchQueue. main. async to avoid blocking the current thread. And potentially even deadlocking your app, which can happen if you call DispatchQueue.
swift 3, 4, 4,2 Synchronous means that thread that initiated that operation will wait for the task to finish before continuing. Asynchronous means that Completes a task in background and can notify you when complete means it will not wait.
One frequent use case for `DispatchQueue. main. async ` in iOS is used when we update UIKit elements after waiting for a network call which happens on a background thread.
As soon as you add heavy tasks to your app like data loading it slows your UI work down or even freezes it. Concurrency lets you perform 2 or more tasks “simultaneously”. The disadvantage of this approach is that thread safety which is not always as easy to control. F.e. when different tasks want to access the same resources like trying to change the same variable on a different threads or accessing the resources already blocked by the different threads.
There are a few abstractions we need to be aware of.
Must be serial or concurrent. As well as global or private at the same time.
With serial queues, tasks will be finished one by one while with concurrent queues, tasks will be performed simultaneously and will be finished on unexpected schedules. The same group of tasks will take the way more time on a serial queue compared to a concurrent queue.
You can create your own private queues (both serial or concurrent) or use already available global (system) queues. The main queue is the only serial queue out of all of the global queues.
It is highly recommended to not perform heavy tasks which are not referred to UI work on the main queue (f.e. loading data from the network), but instead to do them on the other queues to keep the UI unfrozen and responsive to the user actions. If we let the UI be changed on the other queues, the changes can be made on a different and unexpected schedule and speed. Some UI elements can be drawn before or after they are needed. It can crash the UI. We also need to keep in mind that since the global queues are system queues there are some other tasks can run by the system on them.
Queues also have different qos (Quality of Service) which sets the task performing priority (from highest to lowest here):
.userInteractive - main queue
.userInitiated - for the user initiated tasks on which user waits for some response
.utility - for the tasks which takes some time and doesn't require immediate response, e.g working with data
.background - for the tasks which aren't related with the visual part and which aren't strict for the completion time).
There is also
.default queue which does't transfer the qos information.
If it wasn't possible to detect the qos the qos will be used between .userInitiated and .utility.
Tasks can be performed synchronously or asynchronously.
Synchronous function returns control to the current queue only after the task is finished. It blocks the queue and waits until the task is finished.
Asynchronous function returns control to the current queue right after task has been sent to be performed on the different queue. It doesn't wait until the task is finished. It doesn't block the queue.
The most popular mistakes programmers make while projecting the concurrent apps are the following:
NEVER call the sync function on the main queue.
If you call the sync function on the main queue it will block the queue as well as the queue will be waiting for the task to be completed but the task will never be finished since it will not be even able to start due to the queue is already blocked. It is called deadlock.
When to use sync?
When we need to wait until the task is finished. F.e. when we are making sure that some function/method is not double called. F.e. we have synchronization and trying to prevent it to be double called until it's completely finished. Here's some code for this concern:
How to find out what caused error crash report on IOS device?
When you use async
it lets the calling queue move on without waiting until the dispatched block is executed. On the contrary sync
will make the calling queue stop and wait until the work you've dispatched in the block is done. Therefore sync
is subject to lead to deadlocks. Try running DispatchQueue.main.sync
from the main queue and the app will freeze because the calling queue will wait until the dispatched block is over but it won't be even able to start (because the queue is stopped and waiting)
When to use sync
? When you need to wait for something done on a DIFFERENT queue and only then continue working on your current queue
Example of using sync:
On a serial queue you could use sync
as a mutex in order to make sure that only one thread is able to perform the protected piece of code at the same time.
sync
or async
methods have no effect on the queue on which they are called.
sync
will block the thread from which it is called and not the queue on which it is called. It is the property of DispatchQueue
which decides whether the DispatchQueue
will wait for the task execution (serial queue) or can run the next task before current task gets finished (concurrent queue).
So even when DispatchQueue.main.async
is an async call, a heavy duty operation added in it can freeze the UI as its operations are serially executed on the main thread. If this method is called from the background thread, control will return to that thread instantaneously even when UI seems to be frozen. This is because async
call is made on DispatchQueue.main
GCD
allows you to execute a task synchronously
or asynchronously
[About]
synchronous
(block and wait) function returns a control when the task will be completed
asynchronous
(dispatch and proceed) function returns a control immediately, dispatching the task to start to an appropriate queue but not waiting for it to complete.
[DispatchQueue]
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