【问题标题】:How to access an actor-isolated property?如何访问参与者隔离的属性?
【发布时间】:2021-08-29 13:51:38
【问题描述】:

我尝试检查演员的行为。这是 Swift5.5 提供的新特性。

我用官方文档swift.org中的示例代码创建了一个游乐场:

    import Foundation
    
    actor TemperatureLogger {
        let label: String
        var measurements: [Int]
        private(set) var max: Int

        init(label: String, measurement: Int) {
            self.label = label
            self.measurements = [measurement]
            self.max = measurement
        }
    }

    let logger = TemperatureLogger(label: "Outdoors", measurement: 25)
    print(await logger.max)
    // Prints "25"

但是我的编译器在这个例子中失败了:

Swift 编译器错误:

'await' 在一个不支持并发的函数中

Actor 隔离属性 'max' 只能从 Actor 内部引用

那么如何访问参与者隔离的属性?

可能是编译器或示例代码中的错误?

Xcode 版本 13.0 测试版 (13A5154h) 斯威夫特 5.5 版

【问题讨论】:

  • 试试async { print(await logger.max) }。 “Actor-isolated property 'max' can only be referenced from inside the actor”消息似乎毫无帮助...
  • @Sweeper 谢谢,但仍然失败error: Actors.playground:17:1: error: cannot find 'async' in scope async { ^~~~~
  • 我认为异步任务已被弃用

标签: swift swift5.5 xcode13


【解决方案1】:

将访问权限放在Task 块中。 (在早期的 Swift 5.5 测试版中,这曾经被称为 async)。 Actor 隔离属性通过“协作线程池”同步并强制执行独占访问,并且可以挂起,因此需要异步运行。

也不要在 Swift Playground 中尝试这个,在撰写本文时它们似乎不支持 actors(测试版 1)。

let logger = TemperatureLogger(label: "Outdoors", measurement: 25)
Task {
    print(await logger.max)
    // Prints "25"
}

【讨论】:

  • 这只是给我'async(priority:operation:)' is deprecated: `async` was replaced by `Task.init` and will be removed shortly.
  • @KyLeggiero 查看更新的答案。在最新的 Swift 5.5 beta 中,异步任务的创建从 async 更改为 Task,您收到的错误消息清楚地显示了这一点。也许对答案的编辑会比投反对票更有帮助:)
  • 如果您需要当前上下文中的结果,这不起作用...
  • @Era 你的意思是来自同步上下文吗?如果是这样,那么是的,您需要确保您的“上下文”也是异步的,或者使用回调或类似方法来返回结果。例如,同步阻塞并等待结果将违反异步运行时模型。
猜你喜欢
  • 2021-10-13
  • 1970-01-01
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多