Torrontés
Torrontés

Reputation: 197

DispatchQueue.main and thread safety

Consider the following toy example

import SwiftUI

struct WeirdExample: View {
    @State private var greetings = ["Hello", "Bye"]
    @State private var count = 0
    @State private var greetingIndex = 0
    
    func modifyCount() {
        count = (count + 1) % 100
        DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(150) , execute: modifyCount)
    }
    
    var body: some View {
        VStack {
            Spacer()
            Text(greetings[greetingIndex])
            Spacer()
            Button("Change (maybe)"){
                if count % 2 == 0 {
                    greetingIndex = (greetingIndex + 1) % 2
                }
            }
            .padding()
        }
        .onAppear(){modifyCount()}
    }
}

As far as I understand, everything in the example is running on the UI thread. However, I'm concerned by the fact that assigning to the count variable is not atomic. Is it conceivable to have a situation in which pressing the button catches that variable in a weird, undefined state? In other words, is an item dispatched to the main queue guaranteed to run uninterrupted until completion? Of course, being a serial queue guarantees that a job on the queue won't begin executing until the previous ones are finished running, but since there is a distinction between main thread and main queue, I wonder if there is reason for concern about this, or somehow the fact that everything is running on the main thread obviates any problems. Thanks.

Upvotes: 0

Views: 688

Answers (1)

Rob Napier
Rob Napier

Reputation: 299345

but since there is a distinction between main thread and main queue.

The main queue is guaranteed to run on the main thread. It is also where the main RunLoop is, where @MainActor things run, and where the main OperationQueue runs, and all of these things are serialized. While there is a difference between threads and queues (and you're wise to keep that in mind), "main" is the one case where all of the relevant things are equivalent. No, there is no race condition here.

Upvotes: 1

Related Questions