GCD Reference

GCD A key concept in GCD is the queue. The core idea: break a long-running task into multiple units of work and add those units to a . The system manages these queues for us, executing the work units across multiple threads. We don't need to start or manage background threads ourselves. Tasks A task is an operation — in GCD, it's a . Tasks have two execution modes: synchronous and asynchronous. The difference is whether the current thread is blocked. - Synchronous execution: Blocks the current thread and waits for the block to finish before the current thread continues. The compiler may optimize this, so sometimes you'll find the block actually executes on the current thread without creating a new one. - Asynchronous execution: The current thread continues immediately without blocking. Queues A queue holds tasks. There are two types: serial queues and concurrent queues. - Serial queue: GCD dequeues tasks one at a time in FIFO order — execute one, then pull the next, and so on. - Concurrent queue: GCD dequeues tasks in FIFO order, but immediately dispatches each to a different thread. Because tasks are pulled and dispatched quickly, they appear to run simultaneously. GCD controls the level of concurrency based on system resources; when there are many tasks, not all run at the same time. GCD provides three types of queues: - The main queue: Functions like the main thread. Tasks submitted to the main queue execute on the main thread. Obtain it with . Because it is tied to the main thread, it is a serial queue. - Global queues: Concurrent queues shared across the entire process. There are three global queues with high, medium (default), and low priority. Access them with , passing the desired priority. - User queues: (GCD doesn't have an official name for these, but we call them user queues.) Created with . These queues are serial, which makes them useful for synchronization. Deadlocks The code above will deadlock. Why: blocks the current thread (the main thread), while at the same time it must execute on the main thread (). Each is waiting on the other, causing a deadlock. Deadlocks aren't limited to the main thread; they're just most visible there because any user input becomes unresponsive. will never run. Reason: is a serial queue (, also written as ). dispatches work to a new thread separate from the main thread. After printing , blocks while also trying to execute on . Since is blocked waiting for itself, it deadlocks. In short: never synchronously dispatch to a serial queue from within a block already running on that same serial queue. The following two examples are both safe: Common Usage Patterns - with a global concurrent queue: - with a serial queue: - with the main queue: - with the main queue (deadlock): - with a global concurrent queue: - with a serial queue: