Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I conform to a protocol with an actor?

When I try to define an actor that conforms to a protocol, Xcode gives me the error Actor-isolated instance method 'foo()' cannot be used to satisfy nonisolated protocol requirement. I can make the func nonisolated I don't think I want to. Do I need to? What would I be losing if I do so?

Here's the example code that causes the error:

protocol Fooable {
    func foo() -> Int
}

actor Bar: Fooable { // Error: Actor-isolated instance method...
    func foo() -> Int {
        return 42
    }
}
like image 793
Josh Paradroid Avatar asked Aug 31 '25 21:08

Josh Paradroid


1 Answers

If you tap on the “auto fix” button in front of the error message it will expand to show you a few options:

enter image description here

In short, you can either:

  • Add nonisolated to foo() to make this instance method not isolated to the actor:

    protocol Fooable {
        func foo() -> Int
    }
    
    actor Bar: Fooable {
        nonisolated func foo() -> Int {
            return 42
        }
    }
    
  • Mark the protocol requirement foo() async to allow actor-isolated conformance:

    protocol Fooable {
        func foo() async -> Int
    }
    
    actor Bar: Fooable {
        func foo() -> Int {
            return 42
        }
    }
    

There are a few options not included in the “auto fix” alternatives:

  • You can define this as an actor-only protocol:

    protocol Fooable: Actor {
        func foo() -> Int
    }
    
    actor Bar: Fooable {
        func foo() -> Int {
            return 42
        }
    }
    

    For more information, see SE-0306: Actors: Protocol conformances.

  • You can isolate the protocol to a global actor, such as the MainActor. Types that conform to that protocol must/will be isolated to the same global actor, though.

    @MainActor
    protocol Fooable {
        func foo() -> Int
    }
    
    class Bar: Fooable {      // this protocol requirement isolates `Bar` to the same global actor as `Fooable`, i.e., `MainActor` in this case
        func foo() -> Int {
            return 42
        }
    }
    

    This is the pattern adopted by many standard Apple protocols. E.g., UITableViewDataSource is isolated to the main actor.

In short, an isolated method cannot be used to satisfy a nonisolated requirement.


You asked whether you could use nonisolated:

What would I be losing if I do so?

If it is nonisolated, the method simply cannot directly access actor-isolated properties nor call actor-isolated methods. As the method currently stands, you can safely make it nonisolated.

In short, if a method does not require actor-isolation, you should generally feel free to mark it as nonisolated.

like image 115
Rob Avatar answered Sep 03 '25 15:09

Rob