I'm using Swift 6.1.2, and stumbled across something weird. Let's take the below example:
private let myClass = MyClass()
@MainActor
final class MyClass {
private var data: [String: Int] = [:]
init() {}
}
When I try to compile, I get the following error on the first line:
Main actor-isolated default value in a nonisolated context
However, when I remove the default init method, it compiles:
private let myClass = MyClass()
@MainActor
final class MyClass {
private var data: [String: Int] = [:]
}
Why is this? Is it possible to keep the init method in case I want to initiaze data with something else?
Thank you very much!
The init
you wrote is implicitly isolated to the @MainActor
, because the class is marked @MainActor
. On the other hand, the initialiser implicitly generated by Swift is non-isolated, because the compiler can see that it doesn't need to be isolated.
So in the line
private let myClass = MyClass()
you are calling a main actor-isolated initialiser in a non-isolated environment. If this were allowed, situation like this could occur:
actor SomeOtherIsolation {
func f() {
// suppose this is the first time 'myClass' is accessed
// as a result, MyClass.init is called here
// but we can't do that! MyClass.init is main actor isolated, but this code is isolated to SomeOtherIsolation
print(myClass)
}
}
You can write nonisolated init() {}
instead, but based on the fact that MyClass
itself is main actor isolated, it makes more sense to make myClass
main actor isolated too.
@MainActor
private let myClass = MyClass()
Since myClass
is now main actor isolated, you are allowed to call a main actor isolated initialiser here.