Swiftable

Dispatch queues and GCD in Swift 3

Introduction

Said Sikira

Said Sikira

I write code and I love Apple. First thing that I can remember programming was a QBasic calculator in primary school (my professor thought that I couldn't do it). After several years I watched video of Steve Jobs presenting first iPhone and I was hooked. Nowadays, I am an experienced iOS developer with love for Swift and every other Apple platform.


LATEST POSTS

Overdrive released! 18th November, 2016

System frameworks

Dispatch queues and GCD in Swift 3

Posted on .

Grand Central Dispatch (libdispatch) is probably one of the most used technologies on all Apple platforms when it comes to performance, concurrency, parallelization and threading. It was introduced in iOS 4 and written in C programming language (Github repository). Even though Swift is almost 2 years old, using GCD still felt like writing low-level C code and it had none of the Swift language design features. Swift 3 changes that.

Introduction

Let’s start by looking at the dispatch model in GCD. If you ever wanted to do something on the background thread and chances are you did, you typically wrote something like this:

let qosClass = QOS_CLASS_BACKGROUND
let backgroundQueue = dispatch_get_global_queue(qosClass, 0)
dispatch_async(backgroundQueue, {
    print("Work on background queue")
})

You would first create the quality of service class by using QOS_CLASS_BACKGROUND which is instance of qos_class_t, then create the background queue by using system call dispatch_get_global_queue which returns instance of dispatch_queue_t and pass it to dispatch_async call.

As you can see, not very Swift like syntax mainly because it is linked and exposed directly from libdispach library. Some of the class names were sometimes hard to remember and it never looked right when used in code.

New Swift dispatch syntax

Swift 3.0 introduces a completely new set of data structures and dispatch models for Grand Central dispatch. Although most of the APIs are still in beta and not documented, all of the functionality is available.

The new GCD API revolves mostly around the DispatchQueue. Class enables creating and modifying queues, dispatching code synchronously or asynchronously and much more. It utilizes some utility classes like DispatchWorkItem which represents block of code to be dispatched or DispatchQueueAttributes struct which can be used to setup queue.

The simplest way to create a queue is by using default initializer:

let queue = DispatchQueue(label: "com.app.queue")

Or if you want to define some attributes and create the background thread queue you would write:

let backgroundQueue = DispatchQueue(label: "com.app.queue",
                                    qos: .background, 
                                    target: nil)

By using this initializer we passed the queue name and quality of service attribute which is now part of the DispatchQueueAttributes struct. Since DispatchQueueAttributes struct adopts OptionSet protocol, we could simply pass more attributes like whether the queue should perform concurrently or not.

As you can see there is no C style APIs with cryptic names and constants, we use all well known Swift classes, structures and enums.

After you’ve created the queue, you can dispatch code asynchronously by calling async method on the DispatchQueue.

backgroundQueue.async {
    print("Dispatched to background queue")
}

or you can use the sync method to dispatch synchronously. This offers much simpler and easier way to dispatch something without using old dispatch_async call.

Some of the queues that we use often are already present as DispatchQueue instances. For example, if you ever need to dispatch something on the main thread you could simply use:

DispatchQueue.main.async {
    print("main thread dispatch")
}

You can also make use of the global queues by passing the QOS class to the DispatchQueue.

DispatchQueue.global(qos: .userInitiated).async {
    print("user initiated task")
}

You can also use same block of code many times by wrapping it in DispatchWorkItem instance and passing it to DispatchQueue

let block = DispatchWorkItem {
    print("do something")
}
DispatchQueue.main.async(execute: block)

Conclusion

Although still in beta, new GCD API provides flexible and easy Swift syntax that can be adopted by anyone. For the people who have used GCD for years, this is a truly welcoming change. (You could see that when it was announced on WWDC)

You can get more info by checking out official documentation . It is still mostly empty but it should be documented before iOS 10 comes out.

Said Sikira

Said Sikira

https://swiftable.io

I write code and I love Apple. First thing that I can remember programming was a QBasic calculator in primary school (my professor thought that I couldn't do it). After several years I watched video of Steve Jobs presenting first iPhone and I was hooked. Nowadays, I am an experienced iOS developer with love for Swift and every other Apple platform.

  • Alessio Foresta

    Very useful post. Thanks for sharing your knowledge.

  • Rahul Dubey

    Renamed the title from GDC to GCD 🙂

View Comments (2) ...
Navigation