一起养成写作习惯!这是我参与「掘金日新计划 · 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
类来说,它既可以发送事件
也能订阅
,极大的方便了我们的开发。根据我们实际开发需要进行选择。