It is not possible to dispatch function invocation between different threads in Playground unless you do some tricky configuration. All code in this tip should run in an Xcode project instead of Playground, or you may not be able to get the correct result.

GCD is so convenient to use, which ensures programming on multithreads as simple as possible, and improves our experience when handling threads at the same time. Since it is so nice to "keep simple", Apple brings GCD to Swift as expected. More than that, the closure is also added in Swift, which makes it easier and cleaner to work together with GCD. Here I do not intend to introduce GCD's syntax and other features, or this tip would become a GCD 101. A most regular use of GCD in Swift is like this (which I guess covering half of GCD using daily work):

// Create a queue
let workingQueue = dispatch_queue_create("my_queue", nil)

// Dispatch to the newly created queue. GCD take the responsibility for most things.
dispatch_async(workingQueue) {
    // Async work in workingQueue
    NSThread.sleepForTimeInterval(2)  // Simulate for 2 secs executing time

    dispatch_async(dispatch_get_main_queue()) {
        // Return to main queue, update UI here
        print("Work done. Update UI")

UIKit does its work in the main thread. If we do other heavy work in the main thread, the app will be stuck: UI cannot be updated, user input stops responding etc. It is definitely a destruction to user experience, which we must avoid in our app. Those heavy work (applying a filter to an image) or time-consuming work (downloading an image with a cellular network) should be put in a background thread to keep UI smooth and responsive. Once these works done, we can switch back to the main thread to update UI (remember the fact that we need to do all the work with UI in main thread, or there might be unpredictable result).

Another regular use case in everyday work is: invoke a method after several seconds. For example, play animation 2 seconds after view controller transition, or dismiss a pop-up automatically after 3 seconds. There was an instance method of NSObject in Objective-C called -performSelector:withObject:afterDelay:, which could execute a specified selector after some time. However, if you try to use the same thing in Swift project (or other variety of it), you will find it disappeared in the SDK!

What happened? We have emphasized several times that Swift is a SAFE language. In fact, performSelector: is not safe under ARC. ARC will retain all arguments as soon as a method is called, to ensure these arguments will not be dealloced by others unexpected. At the time of leaving the method, the arguments will be released once to equalize the reference count. We cannot pass arguments for some selectors, so the invoked selector may have the argument pointing to an unknown position, it might be a "garbage" in memory, which could cause a crash. Even worse, this kind of issue is not repeatable and very hard to debug.

A possible workaround is using NSTimer to create a timer which will be fired several seconds later. But it is a little heavy: we have to create a new object and introduce a new class, and using Objective-C runtime. We have a better solution for it, just use dispatch_after:

let time: NSTimeInterval = 2.0
let delay = dispatch_time(DISPATCH_TIME_NOW, 
                         Int64(time * Double(NSEC_PER_SEC)))
dispatch_after(delay, dispatch_get_main_queue()) {
    print("print after 2 seconds")

Code is simple. We can even make an encapsulation for it for later use. Another improvement of GCD in iOS 8 is now they could be cancelled. Type of block dispatch_block_t is added into the SDK, by which we could cancel a scheduled block. Before we have to turn to inherit complicated NSOperation, now just GCD could do the magic. It's amazing. Although the code is a bit long, I suggest to read it line by line, to check your understanding on GCD and Swift.

import Foundation

typealias Task = (cancel : Bool) -> ()

func delay(time:NSTimeInterval, task:()->()) ->  Task? {

    func dispatch_later(block:()->()) {
                Int64(time * Double(NSEC_PER_SEC))),

    var closure: dispatch_block_t? = task
    var result: Task?

    let delayedClosure: Task = {
        cancel in
        if let internalClosure = closure {
            if (cancel == false) {
                dispatch_async(dispatch_get_main_queue(), internalClosure);
        closure = nil
        result = nil

    result = delayedClosure

    dispatch_later {
        if let delayedClosure = result {
            delayedClosure(cancel: false)

    return result;

func cancel(task:Task?) {
    task?(cancel: true)

Using it is a lot simpler. If we want to do something 2 seconds later:

delay(2) { print("print after 2 seconds") }

If we need to cancel it, keep the returned value, and call cancel on it:

let task = delay(5) { print("Call 911") }

// Oh, it is the wrong number!