How do I initialize a global variable with @MainActor?

I would like to have some sort of global variable that is synchronized using @MainActor.

Here's an example struct:

@MainActor
struct Foo {}

I'd like to have a global variable something like this:

let foo = Foo()

However, this does not compile and errors with Call to main actor-isolated initializer 'init()' in a synchronous nonisolated context.

Fair enough. I've tried to construct it on the main thread like this:

let foo = DispatchQueue.main.sync {
    Foo()
}

This compiles! However, it crashes with EXC_BAD_INSTRUCTION, because DispatchQueue.main.sync cannot be run on the main thread.

I also tried to create a wrapper function like:

func syncMain<T>(_ closure: () -> T) -> T {
    if Thread.isMainThread {
        return closure()
    } else {
        return DispatchQueue.main.sync(execute: closure)
    }
}

and use

let foo = syncMain {
    Foo()
}

But the compiler does not recognize if Thread.isMainThread and throws the same error message again, Call to main actor-isolated initializer 'init()' in a synchronous nonisolated context.

What's the right way to do this? I need some kind of global variable that I can initialize before my application boots.

(I've also asked this question on Stack Overflow.)

Terms of Service

Privacy Policy

Cookie Policy