如何从另一个ObservableObject类访问@Published变量?
解决Swift中跨ObservableObject访问@Published变量的问题
首先你的代码存在语法错误:DataViewModel类顶层直接写periodViewModel.value = 1是不允许的,这类赋值操作必须放在初始化器、方法或属性初始化闭包内。
以下是正确实现方式,分两种场景处理:
1. 直接获取当前值
如果只是需要在DataViewModel内部读取periodViewModel的最新value,直接访问即可。注意:若DataViewModel自身被SwiftUI视图观察,内部创建的ObservableObject应该用@StateObject而非@ObservedObject(iOS 14+),确保生命周期正确。
import Combine import SwiftUI class PeriodViewModel: ObservableObject { @Published var value = 1 } class DataViewModel: ObservableObject { // 自身创建的ObservableObject用@StateObject @StateObject private var periodViewModel = PeriodViewModel() init() { // 初始化时修改value periodViewModel.value = 1 } // 读取当前最新value的方法 func getLatestValue() -> Int { return periodViewModel.value } // 示例:在方法中修改并读取value func updateValue() { periodViewModel.value += 1 print("更新后的值:\(periodViewModel.value)") } }
2. 监听value的实时更新
如果需要在value发生变化时自动触发逻辑,可通过Combine框架订阅@Published的Publisher:
import Combine import SwiftUI class PeriodViewModel: ObservableObject { @Published var value = 1 } class DataViewModel: ObservableObject { @StateObject private var periodViewModel = PeriodViewModel() // 保存订阅对象,防止被提前释放 private var cancellables = Set<AnyCancellable>() init() { // 订阅value的变化 periodViewModel.$value .sink { [weak self] newValue in guard let self = self else { return } // value更新时执行的逻辑 print("value已更新为:\(newValue)") // 这里可以处理更新后的值,比如同步到其他属性 // self.someOtherProperty = newValue } .store(in: &cancellables) // 初始化赋值 periodViewModel.value = 1 } }
关键说明
@StateObject用于持有自身创建的ObservableObject,@ObservedObject则用于接收从外部传入的实例,不要混用。- 订阅
$value(注意前面的美元符号)可以拿到@Published对应的Combine Publisher,通过sink监听每次值变化。 - 必须将订阅返回的
AnyCancellable存入Set,否则订阅会被立即释放,无法继续监听。
内容的提问来源于stack exchange,提问作者GoddlyGut
相关产品推荐
相关产品推荐

