zum*_*zum 39 actor swift swift-concurrency
我有一个演员:
actor StatesActor {
var job1sActive:Bool = false
...
}
Run Code Online (Sandbox Code Playgroud)
我有一个使用该演员的对象:
class MyObj {
let myStates = StatesActor()
func job1() async {
myStates.job1IsActive = true
}
}
Run Code Online (Sandbox Code Playgroud)
线:
myStates.job1IsActive = true
出现以下错误:
演员隔离属性“job1IsActive”无法从非隔离上下文中发生突变
如何使用 actor 正确存储/读取状态信息,以便 MyObj 可以使用它来读取和设置状态?
mat*_*att 45
如何使用 actor 正确存储/读取状态信息,以便 MyObj 可以使用它来读取和设置状态?
您无法从 Actor 外部更改 Actor 的实例变量。这就是演员的全部意义!
相反,为参与者提供一个设置其自己的实例变量的方法。然后您将能够调用该方法(使用)。await
不允许使用未在参与者上运行的代码中的属性设置器(确切的术语是“参与者隔离代码”)。改变 Actor 状态的最佳位置是 Actor 本身内部的代码。在你的情况下:
actor StatesActor {
var job1IsActive: Bool = false
func startJob1() {
job1IsActive = true
...
}
}
class MyObj {
let myStates = StatesActor()
func job1() async {
await myStates.startJob1()
}
}
Run Code Online (Sandbox Code Playgroud)
异步属性设置器在理论上是可能的,但不安全。这可能就是 Swift 没有它们的原因。编写类似if await actor.a == nil { await actor.a = "Something" }, where actor.acan 在对 getter 和 setter 的调用之间进行更改的内容会变得太容易了。
上面的答案在 99% 的情况下都有效(对于所提出的问题来说已经足够了)。但是,在某些情况下,需要从 Actor 外部的代码更改 Actor 的状态。对于MainActor,使用MainActor.run(body:). 对于全局参与者,@NameOfActor可以应用于函数(并且可以用于定义run类似于 的函数MainActor)。在其他情况下,isolated关键字可以用在函数的 actor 参数前面:
func job1() async {
await myStates.startJob1()
let update: (isolated StatesActor) -> Void = { states in
states.job1IsActive = true
}
await update(myStates)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
34776 次 |
| 最近记录: |