与现有代码集成actors似乎并不像苹果希望您相信的那么简单。考虑以下简单的参与者:
actor Foo {
var value: Int = 0
}
Run Code Online (Sandbox Code Playgroud)
AppKit/UIKit尝试从任何(无任务)控制器访问此属性都是行不通的,因为每个Task控制器都是异步的。
class AppKitController {
func myTaskLessFunc() {
let f = Foo()
var v: Int = -1
Task { v = await f.value }
}
}
Run Code Online (Sandbox Code Playgroud)
这会给你带来预期的错误Mutation of captured var 'v' in concurrently-executing code,而且如果你试图锁定它,它也不会工作。nonisolated演员方法也没有帮助,因为你会遇到同样的问题。
那么,如何在无任务上下文中同步读取参与者属性呢?
小智 13
我找到了一种使用 来做到这一点的方法Combine,如下所示:
import Combine
actor Foo {
nonisolated let valuePublisher = CurrentValueSubject<Int, Never>(0)
var value: Int = 0 {
didSet {
valuePublisher.value = value
}
}
}
Run Code Online (Sandbox Code Playgroud)
通过提供非隔离的发布者,我们可以将 actor 值安全地传播到外部,因为Publishers 是线程安全的。
调用者可以foo.valuePublisher.value从外部访问或订阅它,而不需要异步上下文。
| 归档时间: |
|
| 查看次数: |
2736 次 |
| 最近记录: |