如何使 Actor 的孤立状态可观察

问题描述 投票:0回答:1

假设有一个像下面这样的演员

actor MyActor<State> {
    private var state: State
    
    private init(initialState: State) {
        self.state = initialState
    }
    
    public func message(param: Int) {
        // mutates state
        ...
    }
}

现在我想以某种方式观察隔离属性

state
,以便它可以在 SwiftUI 中使用,它提供视图的状态 - 或其他地方。

目前,观察框架中的

@Observable
宏是没有问题的,因为它目前不支持参与者。

另一个想法是让参与者成为联合发布者,发布

state
独立属性:

所以,我会改变它:

actor MyActor<State> {
    private var _state: CurrentValueSubject<State, Never>
    
    private init(initialState: State) {
        self._state = .init(initialState)
    }
    
    public func message(param: Int) {
        // mutates _state
        ...
    }
}

并且为了成为出版商:

extension MyActor: Publisher {
    public typealias Output = State
    public typealias Failure = Never

    public func receive<S>(
        subscriber: S
    ) where S : Subscriber, Never == S.Failure, State == S.Input {
        _state.receive(subscriber: subscriber)
    }
}

但是,编译器在函数中抱怨(合理)这个错误

receive

Actor-isolated instance method 'receive(subscriber:)' cannot be used 
to satisfy nonisolated protocol requirement

消除此错误的一种方法是: extension MyActor: Publisher { public typealias Output = State public typealias Failure = Never nonisolated public func receive<S>( subscriber: S ) where S : Subscriber, Never == S.Failure, State == S.Input { // Note: probably should declare `_state` nonisolated assumeIsolated { this in this._state.receive(subscriber: subscriber) } } }

现在,通过一些小的努力并应用 
receive(on:)

运算符在主线程上分派值传递,我可以将此参与者集成到

@Observable
类型或符合
ObservableObject
的类型中并使用此“模型”像往常一样在 SwiftUI 中。
但是,它看起来很黑客,我不确定这是否是关于线程安全的正确代码。

也欢迎任何其他让演员“引人注目”的想法。

也许,结论是,“不要使用 actor,使用 @MainActor 和 Final 类”?

swift actor combine
1个回答
0
投票
也许,结论是,“不要使用 actor,使用 @MainActor 和 Final 类”?

是的。请记住,标记为
@MainActor

 的最后一堂课是演员。
    

© www.soinside.com 2019 - 2024. All rights reserved.