以下代码在 Xcode 中的 Swift 6 语言版本下构建时出现错误。这是架构中的问题还是有一个简单的解决方案?类型
Bool
是 Sendable
但它的发布者不是。
Non-sendable type 'Published<Bool>.Publisher' in implicitly asynchronous access to actor-isolated property '$isRecording' cannot cross actor boundary
import Foundation
final class Recorder {
var writer = Writer()
var isRecording = false
func startRecording() {
Task { [writer] in
await writer.startRecording()
print("started recording")
}
}
func stopRecording() {
Task { [writer] in
await writer.stopRecording()
print("stopped recording")
}
}
func observeValues() {
Task {
for await value in await writer.$isRecording.values {
isRecording = value
}
}
}
}
actor Writer {
@Published private(set) public var isRecording = false
func startRecording() {
isRecording = true
}
func stopRecording() {
isRecording = false
}
}
请参阅此屏幕截图,了解我看到的 AVCam 示例代码中的实际错误(唯一的修改是将
@preconcurrency
放入 import AVFoundation
)。
我不会直接使用
@Published
然后获取 values
,而是直接使用 AsyncStream
来传递值。如果流元素可发送,则AsyncStream
是可发送的。
@propertyWrapper
struct Streamed<T: Sendable> {
private var continuation: AsyncStream<T>.Continuation
var projectedValue: AsyncStream<T>
var wrappedValue: T {
didSet {
continuation.yield(wrappedValue)
}
}
init(wrappedValue: T) {
self.wrappedValue = wrappedValue
(projectedValue, continuation) = AsyncStream.makeStream()
continuation.yield(wrappedValue)
}
}
actor Writer {
@Streamed private(set) public var isRecording = false
func startRecording() {
isRecording = true
}
func stopRecording() {
isRecording = false
}
}
然后在
observedValues
,
@MainActor
func observeValues() {
Task {
for await value in await writer.$isRecording {
isRecording = value
}
}
}
请注意,为了确保
isRecording = value
的安全,observeValues
或整个 Recorder
需要与全局参与者隔离。