如何通过Combine在类间传递@Published变量并封装原类?
优雅实现BridgingClass与ClassA的状态同步
你当前的实现可以通过Combine的assign(to:on:)方法简化,同时修复初始化时的未赋值问题,让状态同步更简洁优雅:
基础单向同步方案(ClassA → BridgingClass)
import Combine import SwiftUI @objc public class BridgingClass: NSObject, ObservableObject { // 用Set管理订阅,比单个可选AnyCancellable更规范 private var cancellables = Set<AnyCancellable>() @Published public var isHungry: Bool @objc public init(classA: ClassA) { // 初始化时同步ClassA的初始状态,避免属性未初始化 self.isHungry = classA.hungryState super.init() // 直接将ClassA的hungryState变化绑定到isHungry,无需手动赋值 classA.$hungryState .assign(to: \.isHungry, on: self) .store(in: &cancellables) } }
优化点说明:
- 用
Set<AnyCancellable>管理订阅,替代单个可选的tmpVar,更符合Combine的最佳实践,避免遗漏订阅释放 - 使用
assign(to:on:)直接绑定Publisher输出到属性,省去sink里的手动赋值逻辑,代码更简洁 - 初始化时同步
classA.hungryState的初始值,解决原代码中isHungry未初始化的编译错误
双向同步方案(ClassA ↔ BridgingClass)
如果需要SwiftUI修改isHungry时同步回ClassA的hungryState,可以添加反向绑定:
@objc public class BridgingClass: NSObject, ObservableObject { private var cancellables = Set<AnyCancellable>() private let classA: ClassA // 持有ClassA引用用于反向同步 @Published public var isHungry: Bool @objc public init(classA: ClassA) { self.classA = classA self.isHungry = classA.hungryState super.init() // ClassA → BridgingClass classA.$hungryState .assign(to: \.isHungry, on: self) .store(in: &cancellables) // BridgingClass → ClassA $isHungry .assign(to: \.hungryState, on: classA) .store(in: &cancellables) } }
注意事项:
- 双向同步时需要持有
ClassA的引用,确保反向赋值时对象存在 - 如果
ClassA的hungryState本身支持外部修改(不是只读),这个方案才能生效
内容的提问来源于stack exchange,提问作者Charlie Fish
相关产品推荐
相关产品推荐

