Swift 4中无法创建MyStruct类型RxVariable,求RxSwift解决方案
解决方案:RxSwift实现跨类监听自定义结构体变量
首先,你遇到的无法创建Variable<MyStruct>的问题,大概率是初始化语法错误或者结构体缺少必要的协议支持,下面一步步帮你解决:
1. 修正结构体与Variable的定义
首先,你的MyStruct基础定义没问题,但Variable的初始化语法有误;另外如果要让Variable正确识别结构体内容变化、避免无效的订阅触发,建议让结构体遵循Equatable协议:
import RxSwift import RxCocoa // 让结构体遵循Equatable,方便Variable检测值的变化 struct MyStruct: Equatable { var foo: String = "" var bar: String = "" // Swift 4.0需要手动实现Equatable方法,Swift 4.1+可自动合成 static func == (lhs: MyStruct, rhs: MyStruct) -> Bool { return lhs.foo == rhs.foo && lhs.bar == rhs.bar } } class A { // 修正Variable初始化语法:需要传入初始实例,用=而非:声明 var stct = Variable<MyStruct>(MyStruct()) }
2. 实现B类的监听逻辑
接下来在B类中,正确获取A类实例的Variable并建立订阅,同时要做好DisposeBag的管理以避免内存泄漏:
class B { private let disposeBag = DisposeBag() // 通过初始化参数传入A类实例,建立跨类监听 init(aInstance: A) { aInstance.stct.asObservable() .subscribe(onNext: { newStruct in // 在此获取更新后的结构体实例 print("收到新结构体:foo=\(newStruct.foo),bar=\(newStruct.bar)") }) .disposed(by: disposeBag) } }
3. 测试逻辑示例
你可以通过以下代码验证整个响应式流程:
// 创建A类实例 let a = A() // 创建B类实例并传入A实例,建立监听 let b = B(aInstance: a) // 更新A类中的结构体变量 a.stct.value = MyStruct(foo: "Hello", bar: "RxSwift") // 此时B类的订阅会触发,打印对应内容
4. 重要提醒:Variable的弃用说明
你提到使用最新版本的RxSwift,需要注意:Variable在RxSwift 5.0之后已被官方弃用,推荐使用BehaviorRelay替代。如果后续你升级到适配Swift 4.2+的RxSwift版本,可以改用以下方案:
// A类中替换为BehaviorRelay class A { // BehaviorRelay传入初始值,value为只读,通过accept(_:)更新内容 var stct = BehaviorRelay<MyStruct>(value: MyStruct()) } // B类的订阅逻辑调整 class B { private let disposeBag = DisposeBag() init(aInstance: A) { aInstance.stct.asObservable() .subscribe(onNext: { newStruct in print("收到新结构体:foo=\(newStruct.foo),bar=\(newStruct.bar)") }) .disposed(by: disposeBag) } } // 更新值的方式改为调用accept方法 a.stct.accept(MyStruct(foo: "Updated", bar: "Value"))
常见问题排查
- 如果仍无法创建
Variable<MyStruct>,请确认已正确导入RxCocoa框架(Variable属于RxCocoa,而非RxSwift核心库) - 如果订阅未触发,检查是否通过
Variable的value属性更新值,同时确认Equatable方法实现正确(只有新值与旧值不同时,才会触发订阅)
内容的提问来源于stack exchange,提问作者Saheb Roy
相关产品推荐
相关产品推荐

