All you need to know about GCD in Swift

What is GCD?

DispatchQueue

Serial Queue

Concurrent Queue

  • Concurrent queues help us run multiple tasks at the same time.
  • GCD controls when a particular task in a concurrent queue should start and when and how threads and cores would be used.
  • GCD ensures the tasks are started in the order they are submitted.
  • You can not predict the order of completion of tasks submitted to a concurrent queue.

Asynchronous vs Synchronous execution

  • In a synchronous programming model, tasks are executed one after another. Each task waits for any previous task to be completed and then gets executed.
  • In an asynchronous programming model, when one task gets executed, you could switch to a different task without waiting for the previous one to get completed.
  • You ask the queue to execute the submitted task synchronously.
  • The calling thread is made to wait until the dispatched task has completed execution.
  • You ask the queue to execute the submitted task asynchronously.
  • The calling thread will not wait for the dispatched task to finish.

Main Queue

  • Main queue is a serial queue that runs on the main thread.
  • Main thread is responsible for handling UI events and interactions. Given this fact, the main queue becomes the default and obvious choice to perform UI updates.
  • You should not call sync updates on the main thread as it will block the execution of other UI events, it being a serial queue and this would result in a crash due to deadlock.

Global Queue

  • Global queues are a group of queues that are available to the system for the execution of tasks.
  • There are four types of Global queues in order of their priorities: High, Default, Low, and Background.

Custom Queue

init(label: String, qos: DispatchQoS = .unspecified, attributes: DispatchQueue.Attributes = [], autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency = .inherit, target: DispatchQueue? = nil)
  • label: label is a string identifier that helps us to uniquely identify the queue in various instrumentation tools.
  • qos: When you are invoking any Global queue you specify the QoS of the queue that you want to invoke. We do not directly specify the priorities but do that in the form of QoS classes.
  • attributes: You can specify the attributes for the queue, whether the queue is .serial or .concurrent. If you do not specify any attributes, the queue is a serial queue.
  • autoreleaseFrequency: The frequency at which the objects created by the dispatch queue to schedule your submitted tasks need to be autoreleased.
  • target: The target queue on which the dispatched tasks will execute. Eg. Queue A has a target queue as B. All tasks submitted to queue A will be run on queue B. You can follow this wonderful stack overflow thread to gain more insights on this.
let serialQueues = DispatchQueue(label: "serial-queue")
let concurrentQueue = DispatchQueue(label: "concurrent-queue",attributes: .concurrent)

Quality of Service (QoS)

  • User-interactive: Operations that the user is directly interacting with such as animations or updates to your app’s user interface. This has the highest priority.
  • User-initiated: Operations that are directly initiated by the user. These operations need to be executed quickly.
  • Utility: This represents long-running computations. You should use this QoS for operations such as data import, network calls, etc.
  • Background: This represents operations that the user is not directly aware of. You should use it for maintenance or cleanup tasks that don’t need any user interaction.
  • Default:
  • Unspecified:

Managing Tasks and Shared resources

DispatchWorkItem

DispatchGroup

  • Enter - Call enter() to manually notify the group that a task has started.
  • Leave - Notify the group that this work is done by calling leave().
  • Notify - notify(queue:work:) submits a block to the group which is executed when all tasks have completed execution.

DispatchBarrier

DispatchSemaphore

  1. You set the DispatchSemaphore with an initial value. This value depicts the number of threads that will access the shared resource.
let semaphore = DispatchSemaphore(value: 1)
semaphore.wait()
semaphore.signal()

I would love to hear from you

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store