【发布时间】:2022-01-16 18:31:33
【问题描述】:
将actors 与现有代码集成似乎并不像Apple 希望您相信的那么简单。考虑以下简单的演员:
actor Foo {
var value: Int = 0
}
试图从任何AppKit/UIKit(无任务)控制器访问此属性是行不通的,因为每个Task 都是异步的。
class AppKitController {
func myTaskLessFunc() {
let f = Foo()
var v: Int = -1
Task { v = await f.value }
}
}
这会给你预期的错误Mutation of captured var 'v' in concurrently-executing code,如果你试图锁定它也不会起作用。 nonisolated actor 方法也无济于事,因为您会遇到同样的问题。
那么,如何在无任务上下文中同步读取 actor 属性呢?
【问题讨论】:
-
这就是actor的作用——防止你在执行某些actor方法期间访问属性等。想象一下,如果有一个事务,其中一个actor方法将
10添加到value,然后再次减去10。如果您同步访问它,您可能在value是10时访问它。所以你应该异步阅读它。在您的myTaskLessFunc示例中,v不会设置为函数完成执行的时间。 -
我知道演员是如何工作的,但除非有办法从非异步上下文访问属性,否则有什么意义?在某些时候,您必须将结果转移到演员之外。那么当我不得不回退到类/锁定时,为什么还要使用演员呢?
-
你可以试试
nonisolated:reference -
就像我写的那样,
nonisolated也完全没有意义,因为它只是将问题转移到了不同的位置。我也无法访问nonisolatedfunc 中的 actor 属性。 -
对不起,错过了那部分。对,那是真的。在这种情况下,是什么限制了
myTaskLessFunc成为async?