It is not allowed to use property setters from code that is not run on the actor ("actor isolated code" is the exact terminology). The best place to mutate the state of an actor is from code inside the actor itself. In your case:
actor StatesActor {
var job1IsActive: Bool = false
func startJob1() {
job1IsActive = true
...
}
}
class MyObj {
let myStates = StatesActor()
func job1() async {
await myStates.startJob1()
}
}
Async property setters are in theory possible, but are unsafe. Which is probably why Swift doesn't have them. It would make it too easy to write something like if await actor.a == nil { await actor.a = "Something" }
, where actor.a
can change between calls to the getter and setter.
The answer above works 99% of the time (and is enough for the question that was asked). However, there are cases when the state of an actor needs to be mutated from code outside the actor. For the MainActor
, use MainActor.run(body:)
. For global actors, @NameOfActor
can be applied to a function (and can be used to define a run
function similar to the MainActor
). In other cases, the isolated
keyword can be used in front of an actor parameter of a function:
func job1() async {
await myStates.startJob1()
let update: (isolated StatesActor) -> Void = { states in
states.job1IsActive = true
}
await update(myStates)
}
MyObj
should call that function. – Jadwiga