I'm sure this is ignorance on my part, but I can't seem to grok how the compiler deals with @MainActor. For example, NSApplication inherits from NSResponder which is annotated with @MainActor. This means NSApplication should inherit that behavior. According to SE-0316, in a type annotated with a global actor "all of the methods, properties, and subscripts will implicitly be isolated to that global actor". I would expect this code would require isolation on the MainActor:
class Test {
func getAppearance() -> NSAppearance {
NSApp.effectiveAppearance
}
}
Surprisingly, this code compiles with no warnings. Perhaps a class explicitly annotated as MainActor would raise an error:
extension Test {
func modal() {
NSAlert(error: CancellationError()).runModal()
}
}
Nope, no warnings or errors there either. If I create my own method and annotate it:
extension NSApplication {
@MainActor
var mainProperty: Bool { .random() }
}
extension Test {
func getMain() -> Bool {
NSApp.mainProperty // Error
}
}
Sure enough, the compiler raises the following error: Main actor-isolated property 'mainProperty' can not be referenced from a non-isolated context.
Creating my own class and calling its method gives me this warning: Call to main actor-isolated initializer 'init()' in a synchronous nonisolated context; this is an error in Swift 6
@MainActor
class T {}
extension Test {
func makeT() {
_ = T() // Warning
}
}
Changing the Strict Concurrency Checking build setting to Complete adds errors/warnings to all above examples, but it also warns that NSApp is not concurrency-safe. This means any reference to NSApp would create warnings which is a bit too stingy. The other two settings, Targeted and Minimal behave as described above.
It isn't clear to me how to properly use @MainActor to protect against calling UI code outside the main thread. AppKit classes seem to be ignored which means I would need to sprinkle the annotation all over my UI classes, and any that I overlook wouldn't generate warnings. This seems like a truly useful technology, but it is confounding to understand.