GCD
is used for managing concurrent operations. GCD has lots of benefits like– It improves application performance and responsiveness.
– The app will become more smooth.
– Execute multiple tasks at a time or one by one as per your requirements.
GCD operates at the system level, it is managing the resources in a balanced way for all running application.
Queue
A Queue is a linear structure that follows the First In First Out (FIFO) order. Here we are going to use two types of queueSerial queue
and Concurrent queue
.
Serial Queue
In the serial queue, only one task runs at a time. Once the first task ends then only the second task will begin. All the task follow the same sequence they have to wait until running task finish.Concurrent Queue
In the Concurrent queue, multiple tasks can run at the same time. The start time of the task will be the order they are added, means Task 0 start first then Task 1 will start after that and so on. Tasks can finish in any order.Synchronous vs. Asynchronous
There are two way to dispatch any task usingGCD
, one is synchronous and the second one is asynchronous.
In synchronous function return the control when the task is completed, the caller should wait for the control until the task finish.In the asynchronous function return control immediately, it will not block the current thread, it means the main thread should not wait to finish task running asynchronously.
Main Queue
DispatchQueue.main.async {
// write your code here
}
Global Queue
Global queue is also known as background queue, it is a concurrent queue and shared across all applications. // Synchronous
DispatchQueue.global().sync {
// write your code here
}
// Asynchronous
DispatchQueue.global().async {
// write your code here
}
Quality of Service
In the concurrent queue we can set the priority of the task using Quality of Service class. Basically, we use Quality of Service class depending on how important a task is. Below are the Quality of Services.User-interactive: User-interactive tasks have very high priority and must be finished immediately. Example UI update task, event handling task, animation, etc. User-interactive take high energy and resource as compared to others.
User-initiated: Assing user-initiated to the task that provides immediate results for something the user is doing or the user is waiting for the result and it prevents the user from actively using the app. It has the second priority after the user-interactive Example – the user is waiting for the result, loading email content, etc. Default: The default task has a lower priority than user-interactive and user-initiated. Assign this class to the task that your app initiates or performs active work on the user’s behalf.
Utility: The utility task has a lower priority than the default task. If the user is not required to actively track then assign utility to these tasks. Utility task takes are generally energy-efficient and take less energy.
Background: These tasks have the lowest priority. Assign background to any task which you want to execute when your app is running in the background. These types of tasks generally don’t require any user interaction.
// User-interactive
DispatchQueue.global(qos: .userInteractive).async {
// Event handling task
// Animation task
// Task compete then update UI (in main queue)
}
// User-initiated:
DispatchQueue.global(qos: .userInitiated).async {
// Load conent of email, etc
}
// Defaul
DispatchQueue.global(qos: .default).async {
// task that your app initiates
// performs active work on the user's behalf
}
// Utility
DispatchQueue.global(qos: .utility).async {
//Low priority task
}
// Background
DispatchQueue.global(qos: .background).async {
// task which needs to be executed when the app is running in the background
}
Create a Serial Queue using GCD
Write below code to create your own serial queue. let serialQueue = DispatchQueue(label: "mySerialQueue")
serialQueue.async {
// Add your serial task
}
Let’s download images from an array of image URL in a serial queue.
let myArray = [img1, img2, img3, img4, img5, img6]
for i in 0 ..< myArray.count {
serialQueue.async {
do {
let data = try Data(contentsOf: URL(string: myArray[i])!)
if let image = UIImage(data: data) {
DispatchQueue.main.async {
self.imageSerial[i].image = image
}
}
} catch {
print("error is \(error.localizedDescription)")
}
}
}
Create a Concurrent Queue using GCD
Write below code to create your own serial queue. let concurrentQueue = DispatchQueue(label: "myConcurrentQueue", qos: .default, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil)
concurrentQueue.async {
// Add your concurrent task
}
Let's download images from an array of image URLs in a concurrent queue
let myArray = [img1, img2, img3, img4, img5, img6]
for i in 0 ..< myArray.count {
concurrentQueue.async {
do {
let data = try Data(contentsOf: URL(string: myArray[i])!)
if let image = UIImage(data: data) {
DispatchQueue.main.async {
self.imageConcurrent[i].image = image
}
}
} catch {
print("error is \(error.localizedDescription)")
}
}
}
Dispatch After or Delay Task
If you want to perform any task after some amount of time then you can Dispatch after using the below code.DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
// Code run after 2 seconds
}
Read our next article: UIView shadow and specific corner radius Swift 5
I really appreciate your help with my project!
Nice article
Thank you for your article
This is great tutorial, i have a question, while running the queue the ui is not responding, do you know y. how to solve the issue ?