Concurrent Computing and Programming with Grand Central Dispatch

Thibault Carpentier
4 min readFeb 12, 2018

We are going to study concurent programming with Swift on iOS using the native Grand Central Dispatch ( GCD ) framework. If you are not familiar with concurrent programming I suggest you start by taking a look at wikipedia . Let’s get started by studying the philosophy and good practises behind this API.

Grand Central Dispatch

GCD (Grand Central Dispatch) is a framework that provides low-level APIs to handle concurrent programming on iOS, macOS, tvOS and watchOS platforms. All of the higher-level frameworks that offer competitive management at Apple, such as NSOperation, are based on GCD. These APIs allow you to divide the work of a process into individual tasks, and then help orchestrate the execution of these tasks in parallel or sequentially using a queue. It allows us to abstract from the notion of thread, processor or heart, and optimizes resource management at the same time with its own thread-pool.

The Queues

A fundamental notion on which GCD is based is FIFO (First In, First Out). The tasks that we want to execute will first be inserted into these queues, then GCD will come to retrieve them individually to dispatch them to the right threads / processors / hearts. We can distinguish 2 kinds of file:

  • Concurrent file: Performs multiple tasks in parallel
  • Sequential or Serial file: performs one-to-one tasks in series

Here are the 3 categories of existing files:

  • Main queue : equivalent to the main thread that primarily handles the application's UI. All of the UI calls must be done on this queue.
  • Global queue : the system provides us with 3 global tails with different priorities (HIGH, DEFAULT and LOW). These 3 files are of the Concurrent type.
  • Custom queue : queues that can be created manually and of the desired type (Serial or concurrent).
source

GCD in Practice

Let’s start by creating one of the 3 categories of queues:

For the creation of a custom queue , we first define an identifier (it is recommended to use the reverse-DNS format).

Now that we know how to create files, how do we use them? It’s very simple, thanks to the “dispatcher”! Here is a small example:

Let’s break down all that. We get to start a low priority queue. Then we “dispatch” a block of code asynchronously on the low priority queue previously recovered. This code block asynchronously fetch data to store it in the data variable. Finally we update our view in the main thread with the data recovered. It is important to perform the last step in the main thread because UIKit is not threadsafe and if you update your components in another thread your application may crash or have undefined behavior.

Here the console will show:

before
after
inside async block
inside main Queue block
finished!

Going Deeper

With GCD you can manage all that concerns the concurrent programming. We will see in this section different cases of use a little further.

Let’s discuss a use case where you have several tasks to perform and you want to wait until all these tasks are done before doing anything else. For this it is necessary to use the DispatchGroup :

In order to wait for all the tasks to be done we create a group and in our loop we define when a task starts in the group and especially define when the task is finished. We must imagine this as a counter, each enter this counter is incremented by 1, and each leave it is decremented by 1. At the end we define a notif bloc which listens to the counter of the group and which executes the block in the given queue when he gets to 0. The console output here would be: (Finished job order may differ)

Starting job 0
Starting job 1
Starting job 2
Starting job 3
Starting job 4
Starting job 5
Starting job 6
Starting job 7
Starting job 8
Starting job 9
Finished job 3
Finished job 2
Finished job 1
Finished job 4
Finished job 0
Finished job 9
Finished job 5
Finished job 6
Finished job 8
Finished job 7
All jobs done!

A second very useful case may be wanting to execute code after a certain time. If you have this kind of case immediately think about GCD and its asyncAfter method:

Conclusion

GCD is a very powerful framework that allows you to really get away from the low-level constraints inherent in concurrent programming. However to fully use it to this potential, you need to be careful with shared memory problems and syncronization. Take a deeper look here.

--

--