Friday, March 6, 2026
HomeiOS DevelopmentFixing “reference to var myVariable isn't concurrency-safe as a result of it...

Fixing “reference to var myVariable isn’t concurrency-safe as a result of it includes shared mutable state” in Swift


Revealed on: August 15, 2024

When you begin migrating to the Swift 6 language mode, you will almost definitely activate strict concurrency first. As soon as you’ve got executed this there will probably be a number of warings and errors that you’re going to encounter and these errors could be complicated at occasions.

I will begin by saying that having a stable understanding of actors, sendable, and knowledge races is a large benefit while you need to undertake the Swift 6 language mode. Just about all the warnings you will get in strict concurrency mode will let you know about potential points associated to working code concurrently. For an in-depth understanding of actors, sendability and knowledge races I extremely advocate that you just check out my Swift Concurrency course which can get you entry to a collection of movies, workout routines, and my Sensible Swift Concurrency guide with a single buy.

WIth that out of the way in which, let’s check out the next warning that you just may encounter in your undertaking:

reference to var myVariable isn’t concurrency-safe as a result of it includes shared mutable state

There are a number of causes for this warning to pop up in Xcode. For instance, the code beneath would trigger Xcode to warn us:

// Var 'myVariable' isn't concurrency-safe as a result of it's nonisolated international shared mutable state; that is an error within the Swift 6 language mode
var myVariable = UUID()

func randomCharacter() async -> Character {
    myVariable = UUID()
    return myVariable.uuidString.randomElement() ?? "1"
}

The next code makes myVariable a static var which leads to the identical warning being proven:

struct CharacterMaker {
    // Var 'myVariable' isn't concurrency-safe as a result of it's nonisolated international shared mutable state; that is an error within the Swift 6 language mode
    static var myVariable = UUID()

    static func randomCharacter() async -> Character {
        myVariable = UUID()
        return myVariable.uuidString.randomElement() ?? "1"
    }
}

The Swift compiler considers any globally accessible var to be unsafe from a concurrency standpoint. The rationale for that’s that nothing is stopping us from making a number of calls to randomCharacter concurrently which might lead to a knowledge race on myVariable. We might find yourself with a number of learn and write operations on the similar time.

To repair this, myVariable ought to both be moved into an actor or be remoted to a worldwide actor.

For instance, you can isolate myVariable to @MainActor like this:

// with a worldwide variable
@MainActor
var myVariable = UUID()

// or as a static property
struct CharacterMaker {
    @MainActor
    static var myVariable = UUID()
    // ...
}

The draw back of that is, after all, that we must be on the primary actor to work together with the variable. You’ll be able to work round this by defining your individual (empty) international actor which can be certain that our accesses are on the worldwide executor as an alternative of the primary actor:

@globalActor
actor GlobalIsolator {
  static let shared = GlobalIsolator()
}

@GlobalIsolator
var myVariable = UUID()

// or as a static property
struct CharacterMaker {
    @GlobalIsolator
    static var myVariable = UUID()
    // ...
}

This makes accessing myVariable a bit much less handy since you’ll want to put your self on the GlobalIsolator actor when interacting with myVariable:

@GlobalIsolator
static func randomCharacter() async -> Character {
    myVariable = UUID()
    return myVariable.uuidString.randomElement() ?? "1"
}

In some circumstances you will know that although the compiler does not like your shared mutable state, you know that it is tremendous because of the means your code is structured.

If that is the case, and also you’re completely 100% certain that you just will not have any points associated to your shared mutable state, you should use nonisolated(unsafe) in your variable to inform the compiler that the dearth of isolation is intentional and that you just’re conscious of its knowledge issues of safety:

// with a worldwide variable
nonisolated(unsafe) var myVariable = UUID()

// or as a static property
struct CharacterMaker {
    nonisolated(unsafe) static var myVariable = UUID()
    // ...
}

You need to solely use nonisolated(unsafe) as a last-resort answer as a result of the compiler will now not have the opportunity that can assist you detect potential knowledge races round myVariable.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments