一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第15天,点击查看活动详情。
- 继续介绍剩下的几种
subject类型的使用和原理简单分析
1. ReplaySubject
相比较我们之前分析的BehaviorSubject会保存一个默认值,我们的ReplaySubject可以设置我们自己想要保存的元素。看个例子
/// 自定义保存值的数组大小
func ReplaySubjectMethod() {
let ReplaySubject = ReplaySubject<Int>.create(bufferSize: 3)
ReplaySubject.onNext(4)
ReplaySubject.onNext(5)
ReplaySubject.onNext(6)
ReplaySubject.subscribe(onNext: {print("ReplaySubject首次订阅",$0)})
.disposed(by: disposeBag)
ReplaySubject.onNext(7)
ReplaySubject.subscribe(onNext: {print("ReplaySubject再次订阅",$0)})
.disposed(by: disposeBag)
}
打印结果
可以发现保存的是最新的3个元素,因为我们初始化的时候
bufferSize设置的大小为3。类似我们的数组的大小
- 分析
初始化判断bufferSize是否为1走不同的初始化
先看下ReplayOne
会保存我们最新发送的元素,
replayBuffer的时候观察者调用on方法发送
ReplayMany
这里继承于
ReplayManyBase,属性queue是一个数组用来存放我们的观察者发送的元素。
- 发送事件
当我们发送next事件,调用on的时候会往数组中加入我们的element
- 订阅
会调用replayBuffer(),我们上面在ReplayManyBase和ReplayOne中进行了重写 ,也就是向当前订阅者发送保存的element元素。同样的把我们的观察者回调事件加入obsevers中。
2.AsyncSubject
AsyncSubject再
/// 在完成序列后发送最后一次的值
func AsyncSubjectMethod() {
let asyncSubject = AsyncSubject<Int>.init()
asyncSubject.onNext(4)
asyncSubject.onNext(5)
asyncSubject.onNext(6)
asyncSubject.subscribe(onNext: {print("asyncSubject首次订阅",$0)})
.disposed(by: disposeBag)
asyncSubject.onNext(7)
asyncSubject.subscribe(onNext: {print("asyncSubject再次订阅",$0)})
.disposed(by: disposeBag)
asyncSubject.onCompleted()
}
可以看到多了一个isStopped状态,和stoppedEvent事件,并定义了set方法。
定义了lastElement元素。
- On 当发送事件的时候
当.next事件时候保存元素,并且初始化一个空的eventHandle数组,当为complete的时候则先判断是否存在最后一个元素,存在的话赋值stoppedEvent,并发送next事件。否则发送complete事件
根据event事件进行判断.只有我们发送complete事件才能到next事件。
在dispatch中调用事件回调,这里先调用我们next事件,之后调用complete事件。
- 小结
对于
AsyncSubject类来说,当我们发送事件onNext事件的时候并不会调用我们事件,只有当我们发送on Completed事件的时候才会向所有订阅者的事件回调发送最后一次保存的元素element,结束序列。
3. BehaviorRelay
对于我们序列发送的元素我们每次订阅才能获取,是否可以主动获取呢?
func BehaviorRelayMethod() {
let behaviorRelay = BehaviorRelay<Int>(value: 2)
print(behaviorRelay.value)
behaviorRelay.subscribe(onNext: {print($0)})
.disposed(by: disposeBag)
behaviorRelay.accept(20)
}
类似我们的BehaviorSubject,不能发送error和complete事件
打印结果
- 分析
其实就是对BehaviorSubject的封装,不能发送error和complete事件,同时可以获取发送的value值
当发送的时候使用accept替代我们的onNext(event)
4. 总结
对于我们的subject类来说,它既可以发送事件也能订阅,极大的方便了我们的开发。根据我们实际开发需要进行选择。