#18: Background Threads in Swift

Heavy work should not run on the main thread. Image processing, parsing, network post-processing and other expensive tasks should be moved to a background queue, then UI updates should be dispatched back to the main queue.

In modern Swift the simplest tool for this job is DispatchQueue:

DispatchQueue.global(qos: .userInitiated).async {
    let image = renderLargePreview()
    let metadata = computeMetadata()

    DispatchQueue.main.async {
        self.imageView.image = image
        self.statusLabel.text = metadata.title
    }
}

Use .main only for UIKit/AppKit work and keep the block small. For long-running operations, choose a queue quality-of-service such as .userInitiated, .utility, or .background depending on how urgent the task is.

If you need a refresher on queue creation and QoS values, see #09: Creating DispatchQueues in Swift 3.

If the work has dependencies, cancellation, or progress reporting, OperationQueue or Swift concurrency (Task) can be a better fit, but the idea stays the same: expensive work off the main queue, UI updates back on the main queue.


I'm also on Twitter and GitHub.

Subscribe via RSS.