Skip to content

[swift2objc] Add support for Actors #2052

@nikeokoronkwo

Description

@nikeokoronkwo

From https://docs.swift.org/swift-book/documentation/the-swift-programming-language/concurrency#Actors:

You can use tasks to break up your program into isolated, concurrent pieces. Tasks are isolated from each other, which is what makes it safe for them to run at the same time, but sometimes you need to share some information between tasks. Actors let you safely share information between concurrent code.
Like classes, actors are reference types, so the comparison of value types and reference types in Classes Are Reference Types applies to actors as well as classes...

actor MyActor {
  public let constValue: Int = 9
  public var myValue: String

  public init(_ myValue: String) {
    self.myValue = myValue
  }

  public func myFunc() {
    print("myFunc called with \(myValue)...")
  }
}

let actorObject = MyActor("Value")
await actorObject.myFunc()
var value = await actorObject.myValue

A few things to keep in mind are:

  • By default, you cannot export properties in actors with @objc by default, unless they are marked with nonisolated, which means the property is immutable (a let property, or a getter). A workaround may be needed to set and get properties, one of which can be to add a "get" and "set" async function pair for each needed property, since async functions can be exported to Objective-C (as actors are async by default).
    @objc public actor MyObjCActor {
      // This is just an example. In the real implementations, there will be a wrapped value of the original Actor
    
      public var myValue: String
      @objc public func getMyValue() async -> String {
        return myValue;
      }
      @objc public func setMyValue(_ newValue: String) {
         myValue = newValue;
      }
    
      // ...
    }
  • They also do not support exporting functions with @objc by default unless they are marked with nonisolated or the function is asynchronous. This might require similar workarounds, where the wrapper implementation has the function as async.
  • Actors do not support subscripts in @objc, and since subscripts cannot be async, an async getter function will be needed to replace this, with similar workaround as the previous.

Similar functionality may follow similar async-ing as described.

Other than that, actors can be expressed as CompountDeclarations, as they are represented similar to, if not same as, classes in Objective-C.


This issue also tracks adding support for isolated parameters using Actors. Since they are both very related, they can be fine in the same issue

From https://github.com/swiftlang/swift-evolution/blob/main/proposals/0313-actor-isolation-control.md:

A function can become actor-isolated by indicating that one of its parameters is isolated. For example, the deposit(amount:) operation can now be expressed as a module-scope function as follows:

func deposit(amount: Double, to account: isolated BankAccount) {
  assert(amount >= 0)
  account.balance = account.balance + amount
}

The only thing to note is that isolated parameters require the function to be async when exporting to @objc, so the wrapper implementation will need to have the new function as async

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions