Chapters

Hide chapters

Concurrency by Tutorials

Third Edition · iOS 16 · Swift 5.7 · Xcode 14

2. GCD vs. Operations
Written by Scott Grosch

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

There are two APIs that you’ll use when making your app concurrent: Grand Central Dispatch, commonly referred to as GCD, and Operations. These are neither competing technologies nor something that you have to exclusively pick between. In fact, Operations are built on top of GCD!

Grand Central Dispatch

GCD is Apple’s implementation of C’s libdispatch library. Its purpose is to queue up tasks — either a method or a closure — that can be run in parallel, depending on availability of resources; it then executes the tasks on an available processor core.

Note: Apple’s documentation sometimes refers to a block in lieu of closure, since that was the name used in Objective-C. You can consider them interchangeable in the context of concurrency.

While GCD uses threads in its implementation, you, as the developer, do not need to worry about managing them yourself. GCD’s tasks are so lightweight to enqueue that Apple, in its 2009 technical brief on GCD, stated that only 15 instructions are required for implementation, whereas creating traditional threads could require several hundred instructions.

All of the tasks that GCD manages for you are placed into GCD-managed first-in, first-out (FIFO) queues. Each task that you submit to a queue is then executed against a pool of threads fully managed by the system.

Note: There is no guarantee as to which thread your task will execute against.

Synchronous and Asynchronous Tasks

Work placed into the queue may either run synchronously or asynchronously. When running a task synchronously, your app will wait and block the current run loop until execution finishes before moving on to the next task. Alternatively, a task that is run asynchronously will start, but return execution to your app immediately. This way, the app is free to run other tasks while the first one is executing.

// Class level variable
let queue = DispatchQueue(label: "com.yourcompany.worker")

// Somewhere in your function
queue.async {
  // Call slow non-UI methods here

  DispatchQueue.main.async {
    // Update the UI here
  }
}

Serial and Concurrent Queues

The queue to which your task is submitted also has a characteristic of being either serial or concurrent. Serial queues only have a single thread associated with them and thus only allow a single task to be executed at any given time. A concurrent queue, on the other hand, is able to utilize as many threads as the system has resources for. Threads will be created and released as necessary on a concurrent queue.

Asynchronous Doesn’t Mean Concurrent

While the difference seems subtle at first, just because your tasks are asynchronous doesn’t mean they will run concurrently. You’re actually able to submit asynchronous tasks to either a serial queue or a concurrent queue. Being synchronous or asynchronous simply identifies whether or not the queue on which you’re running the task must wait for the task to complete before it can spawn the next task.

Operations

GCD is great for common tasks that need to be run a single time in the background. When you find yourself building functionality that should be reusable — such as image editing operations — you will likely want to encapsulate that functionality into a class. By subclassing Operation, you can accomplish that goal!

Operation Subclassing

Operations are fully-functional classes that can be submitted to an OperationQueue, just like you’d submit a closure of work to a DispatchQueue for GCD. Because they’re classes and can contain variables, you gain the ability to know what state the operation is in at any given point.

Bonus Features

But wait, there’s more! Operations provide greater control over your tasks as you can now handle such common needs as cancelling the task, reporting the state of the task, wrapping asynchronous tasks into an operation and specifying dependences between various tasks. Chapter 6, “Operations,” will provide a more in-depth discussion of using operations in your app.

BlockOperation

Sometimes, you find yourself working on an app that heavily uses operations, but find that you have a need for a simpler, GCD-like, closure. If you don’t want to also create a DispatchQueue, then you can instead utilize the BlockOperation class.

Which Should You Use?

There’s no clear-cut directive as to whether you should use GCD or Operations in your app. GCD tends to be simpler to work with for simple tasks you just need to execute and forget. Operations provide much more functionality when you need to keep track of a job or maintain the ability to cancel it.

Where to Go From Here?

To the next chapter, of course! The rest of the book will examine, in detail, both Grand Central Dispatch and Operations. By the time you’ve completed the book you’ll have a solid grasp on what both options provide, as well as a better idea on how to choose one over the other.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2024 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now