1

与现有代码集成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演员方法也无济于事,因为你会遇到同样的问题。

那么如何在无任务上下文中同步读取参与者属性呢?

4

1 回答 1

1

我找到了一种使用 的方法Combine,如下所示:

import Combine

actor Foo {

    nonisolated let valuePublisher = CurrentValueSubject<Int, Never>(0)

    var value: Int = 0 {
        didSet {
            valuePublisher.value = value
        }
    }
}

通过提供一个非隔离的发布者,我们可以将actor值安全地传播到外部,因为Publishers 是线程安全的。

调用者可以foo.valuePublisher.value从外部访问或订阅它,而不需要异步上下文。

于 2021-12-14T14:22:52.963 回答