[Pitch] Global actors

  • An overridden declaration propagates its global actor attribute (if any) to its overrides mandatorily. Other forms of propagation do not apply to overrides. It is an error if a declaration with a global actor attribute overrides a declaration without an attribute.

I assume this means that overridden declarations from a non-isolated superclass are not actor-isolated to the global actor, which would mean that in the following code, viewDidAppear would not be actor-isolated:

@MainActor
class IconViewController: UIViewController {
  var url: URL?

  override func viewDidAppear() {
    // Error: cannot access actor-isolated property 'url'
    // from non-isolated context
    self.url = URL(string: "https://example.org")!
  }
}

This seems annoying, since viewDidAppear is always going to be called on the main thread (as per the UIKit/AppKit framework). Is there any mechanism proposed whereby ObjC code can declare a type as actor-isolated?


The pitch also showed an example of an ObjC-exposed global-actor-tagged property:

class IconViewController: UIViewController {
  @MainActor @objc private dynamic var icons: [[String: Any]] = []
  // ...
}

This won't be exposed to ObjC because it's private. But if it were not private, what would such a declaration look like in ObjC? Is the actor-isolation preserved in any way when exposed to ObjC? If so, how? If not, does that expose a potentially source of unsafety, where a caller might access a @MainActor property from a background thread in ObjC? Maybe that unsafety is acceptable, similar to how ObjC code can pass nil to a non-optional parameter, but I think it would be useful to define the proposed behavior.