Grand Central Dispatch Tutorial Swift 5

The Grand Central Dispatch (GCD) is a is a low-level API provided by Apple. 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 queue Serial 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 using GCD, 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.

Unspecified: When quality-of-service class is not present then it will be treated as unspecified.
  // 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

2 comments on “Grand Central Dispatch Tutorial Swift 5

Leave a Reply

Your email address will not be published. Required fields are marked *