SwiftUI中@Observable属性适配.onReceive()的问题咨询
问题解决:在@Observable属性上使用.onReceive()
错误原因
你遇到的错误是因为.onReceive(_:perform:)要求接收的参数必须遵循Publisher协议,但myData.isReady是Bool类型,并不符合这个要求,所以编译器报错。
实现.onReceive()的可行方案
在@Observable类中,单个属性默认不会自动成为Publisher,但你可以通过Combine框架的CurrentValueSubject(或PassthroughSubject)将属性封装为Publisher,从而适配.onReceive()的要求。
步骤1:修改可观察对象类
将isReady替换为CurrentValueSubject<Bool, Never>类型,它本身就是一个Publisher,可以发送值的变化:
import Combine import Observation @Observable class MyObservableObject { // 用CurrentValueSubject包装Bool值,初始值设为false var isReady = CurrentValueSubject<Bool, Never>(false) var isDoneFetching = false func fetchStuff() { // 模拟异步数据请求 DispatchQueue.main.asyncAfter(deadline: .now() + 2) { self.isDoneFetching = true // 发送isReady状态更新 self.isReady.send(true) } } }
步骤2:在视图中使用.onReceive()
现在myData.isReady是合法的Publisher,可以直接传入.onReceive():
private var myData = MyObservableObject() VStack { // 视图内容 } .onAppear { myData.fetchStuff() } .onReceive(myData.isReady) { isReady in if isReady { formatUIData() } }
补充说明
CurrentValueSubject会保存当前值,新订阅者会立即收到最新值;如果不需要保存当前值,可改用PassthroughSubject。- 如果你不想引入Combine的Subject,也可以通过
myData.objectWillChange(@Observable类自带的Publisher)监听整个对象的变化,但这会在任意属性更新时触发,不如单个属性的Subject精准。
内容的提问来源于stack exchange,提问作者William T.
相关产品推荐
相关产品推荐

