Swift
concurrency
dispatchqueue
GCD
asynchronous-programming

How do I dispatch_sync, dispatch_async, dispatch_after, etc in Swift 3, Swift 4, and beyond?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

In the realm of concurrent programming with Swift, Apple’s Grand Central Dispatch (GCD) provides powerful, low-level API capabilities. Understanding and leveraging functions like dispatch_sync, dispatch_async, and dispatch_after can significantly enhance both performance and responsiveness of your applications. This article delves into the mechanics of these functions and illustrates their usage across Swift 3, Swift 4, and beyond.

Grand Central Dispatch (GCD)

GCD is a robust framework that supports executing code concurrently, allowing developers to leverage multi-core processors effectively. The Swift API makes it easier to work with GCD through simplified function calls such as DispatchQueue.

1. dispatch_sync

The dispatch_sync function is used to execute a block of code synchronously on a specified dispatch queue. When called, it doesn't return until the block is finished executing.

Usage

swift
1let concurrentQueue = DispatchQueue(label: "com.example.queue", attributes: .concurrent)
2
3concurrentQueue.sync {
4    // This task runs on the specified queue
5    print("Executing synchronous task")
6    // Perform your synchronous task here
7}
8print("This line waits for the completion of the previous block")

Key Points:

  • Blocks Main Thread: If used on the main thread, it will block it—potentially freezing the UI.
  • Use with Caution: Preferably used for tasks that must complete before continuing execution.

2. dispatch_async

Unlike dispatch_sync, dispatch_async allows the block of code to execute asynchronously, which means the function returns immediately to the caller while the block executes potentially on a different thread.

Usage

swift
1let concurrentQueue = DispatchQueue(label: "com.example.queue", attributes: .concurrent)
2
3concurrentQueue.async {
4    // This task runs asynchronously
5    print("Executing asynchronous task")
6    // Perform your asynchronous task here
7}
8print("This line executes immediately after the async call")

Key Points:

  • Non-Blocking: Does not block the calling thread, allowing it to return immediately.
  • Ideal for Non-UI Operations: Very useful for tasks like data processing, file I/O, or network requests.

3. dispatch_after

The dispatch_after function provides functionality to execute a block of code after a specified delay. This is particularly useful for deferred actions you want to execute periodically or after a slight delay.

Usage

swift
1let delayQueue = DispatchQueue(label: "com.example.queue")
2
3let delayTime: DispatchTime = .now() + 2.0 // 2 seconds delay
4delayQueue.asyncAfter(deadline: delayTime) {
5    print("This will execute after a 2 second delay")
6    // Execute tasks that require delay
7}

Key Points:

  • Timed Execution: Execute tasks after a delay without blocking the execution thread.
  • Scheduling Tasks: Fits tasks that need deferred execution for animation or timeouts.

Summary Table

FunctionExecution TypeEffectsUse Cases
dispatch_syncSynchronousBlocks the calling threadSequential task execution where continuation is not possible until completion. Avoid on Main Thread to prevent UI blocking.
dispatch_asyncAsynchronousNon-blockingFire-and-forget tasks such as network calls, Ideal for background processing.
dispatch_afterAsynchronous (with delay)Non-blockingDelayed task execution avoiding busy-waiting. Useful for scheduling tasks.

Advanced Usage and Considerations

Quality of Service (QoS)

Swift allows setting QoS to guide the system on the relative importance of tasks. As of Swift 4 and beyond, QoS can be applied to DispatchQueue:

swift
1let highPriorityQueue = DispatchQueue(label: "com.example.queue", qos: .userInitiated)
2
3highPriorityQueue.async {
4    // Execute time-critical task
5}

QoS Classes:

  • .background: Non-critical tasks like data prefetching.
  • .utility: Tasks requiring a reasonable time to execute without user impact.
  • .userInitiated: Operations related to user actions that need immediate results.
  • .userInteractive: Tasks that affect UI updates or animations.

Sync vs. Async Considerations

Choosing between synchronous and asynchronous execution affects your application's UI and responsiveness. Asynchronous execution is usually preferred, especially for UI applications, to keep the user interface responsive.

Thread Safety

Always remember thread safety when accessing shared resources. Use barriers or semaphores if tasks may lead to data races or inconsistencies.

By understanding these dispatch functions and their proper usage, developers can write efficient, responsive, and robust Swift applications. Mastery of GCD is a critical component of any serious iOS and macOS developer’s toolkit.


Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions