Grand Central Dispatch


Threads allows you to execute multiple code paths concurrently within your application. The reason you’ll use it is to speed up the performance of your application by running some code on another thread while other operations are happening on the main thread. This is helpful for when you need to pre-load data. The disadvantage of this is that adding threads can cause behavioral changes or even crash your application, as threads are complicated to deal with.

Grand Central Dispatch, or GCD for short, is a technology Apple provides that makes it (slightly) easier to perform simultaneous operations in iOS. These are vital to any iOS application as they allow the program to perform long operations without freezing or blocking the user interface. GCD works by allowing specific tasks in a program that can be run in parallel to be queued up for execution.

With GCD, tasks are described as blocks, while queues are used to organize these blocks based on how you believe they need to be executed. The blocks or operations, will be dispatched in the queue to another thread, leaving the main thread to continue updating the UI and responding to user events while the other threads are working in the background.

Blocks

Blocks are a huge part of what makes GCD work so efficiently. A block in code is denoted by a caret at the beginning of a function. For example, you could declare a block and assign it to “x” by writing:

x = ^{printf("Hello World");}

This turns the variable “x” into a way of calling the function so
that calling “x( );” in the code would print the words hello world. Blocks allow for much more complex functions, such as large arguments and data-pulls, to be wrapped in a way that is easily passed around a program.

Queues

Queues provide the intelligence behind GCD. A dispatch queue is an object-like structure that manages the tasks you submit to it. A dispatch queue can be either concurrent or serial. A concurrent queue will execute many jobs simultaneously (do not wait with the next job until any previous ones finish), a serial queue will only execute one job at a time. The tasks are always executed in a first-in, first-out order (FIFO) in both queue types.

Serial queues are monogamous, but uncommitted. If you give a bunch of tasks to each serial queue, it will run them one at a time, using only one thread at a time. The uncommitted aspect is that serial queues may switch to a different thread between tasks. Serial queues always wait for a task to finish before going to the next one. Thus tasks are completed in FIFO order.

The main queue is a special serial queue. Unlike other serial queues, which are uncommitted, in that they are “dating” many threads but only one at a time, the main queue is “married” to the main thread and all tasks are performed on it. Jobs on the main queue need to run efficiently and correctly so that small operations don’t block the UI, which relies solely on the main thread for reacting to user events.

If serial queues are monogamous, then Concurrent queues are promiscuous as they will submit tasks to any available thread or even make new threads depending on system load. They may perform multiple tasks simultaneously on different threads. Tasks are submitted for execution in FIFO order, but order of completion is not guaranteed.

Visualizing Grand Central Dispatch: