RxSwift中如何向BehaviorSubject<[]>追加元素?及RxSwift4中Variable废弃后的替代方案
RxSwift: 追加BehaviorSubject数组元素 & 替代废弃的Variable
1. 向BehaviorSubject<[Element]>追加元素
BehaviorSubject本身没有直接的"追加"API,它的核心逻辑是向订阅者发送完整的新值。要实现数组元素追加,你需要先获取它当前持有的数组,在这个数组上完成追加操作,再把更新后的完整数组发送给subject。
举个实际的代码例子,假设我们维护一个存储字符串的BehaviorSubject:
// 初始化一个空数组的BehaviorSubject let stringSubject = BehaviorSubject<[String]>(value: []) // 封装追加元素的方法 func appendNewString(_ newStr: String) { do { // 获取当前数组值 var currentArr = try stringSubject.value // 追加新元素 currentArr.append(newStr) // 发送更新后的数组 stringSubject.onNext(currentArr) } catch { // 处理获取值失败的情况(如果初始化有默认值,这里一般不会触发) print("获取当前数组失败: \(error.localizedDescription)") } }
如果你的场景能确定不会出现获取value的错误(比如始终有初始值、从未发送过error事件),也可以简化成更简洁的写法:
func appendNewString(_ newStr: String) { guard var currentArr = try? stringSubject.value else { return } currentArr.append(newStr) stringSubject.onNext(currentArr) }
2. 用BehaviorSubject替代废弃的Variable
RxSwift 4之后Variable被正式废弃,它的核心特性是:
- 拥有可读写的
value属性 - 新订阅者会立即收到当前的
value - 修改
value时自动向订阅者发送新值
用BehaviorSubject实现完全等效的功能,有两种常用方式:
方式1:封装自定义类(贴近原Variable的使用体验)
class BehaviorRelay<Element> { private let subject: BehaviorSubject<Element> private var _value: Element /// 可读写的value属性,和原Variable一致 var value: Element { get { _value } set { _value = newValue subject.onNext(newValue) } } init(value: Element) { self._value = value self.subject = BehaviorSubject(value: value) } /// 转换为Observable供订阅,对应原Variable的asObservable() func asObservable() -> Observable<Element> { subject.asObservable() } }
使用起来和原来的Variable几乎没有区别:
// 初始化 let userNameRelay = BehaviorRelay(value: "Jack") // 读取值 print(userNameRelay.value) // 输出 "Jack" // 修改值 userNameRelay.value = "Mike" // 订阅更新 userNameRelay.asObservable() .subscribe(onNext: { print("当前用户名: \($0)") }) .disposed(by: disposeBag)
方式2:直接使用BehaviorSubject(轻量方案)
如果不想自定义类,也可以直接用BehaviorSubject配合计算属性实现:
private let ageSubject = BehaviorSubject<Int>(value: 25) // 封装读写逻辑 var userAge: Int { get { try! ageSubject.value } // 确定无错误时用try!,追求安全可以用try?加默认值 set { ageSubject.onNext(newValue) } } // 订阅时调用asObservable() ageSubject.asObservable() .subscribe(onNext: { print("当前年龄: \($0)") }) .disposed(by: disposeBag)
注意:使用
try!的前提是你能保证BehaviorSubject不会进入error状态,否则会触发崩溃。如果需要更严谨的错误处理,可以用try?并提供合理的默认值。
内容的提问来源于stack exchange,提问作者Jack Guo
相关产品推荐
相关产品推荐

