RxSwift学习-13-Subject的使用(下)

一起养成写作习惯!这是我参与「掘金日新计划 · 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)

    

    }
复制代码

打印结果

image.png 可以发现保存的是最新的3个元素,因为我们初始化的时候bufferSize设置的大小为3。类似我们的数组的大小

  • 分析

初始化判断bufferSize是否为1走不同的初始化

image.png

先看下ReplayOne

image.png 会保存我们最新发送的元素,replayBuffer的时候观察者调用on方法发送

  • ReplayMany

image.png 这里继承于ReplayManyBase,属性queue是一个数组用来存放我们的观察者发送的元素。

  • 发送事件

image.png

当我们发送next事件,调用on的时候会往数组中加入我们的element

  • 订阅

image.png

会调用replayBuffer(),我们上面在ReplayManyBaseReplayOne中进行了重写 ,也就是向当前订阅者发送保存的element元素。同样的把我们的观察者回调事件加入obsevers中。

image.png

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()

    

    }
复制代码

image.png

可以看到多了一个isStopped状态,和stoppedEvent事件,并定义了set方法。 定义了lastElement元素

  • On

当发送事件的时候

image.png

.next事件时候保存元素,并且初始化一个空的eventHandle数组,当为complete的时候则先判断是否存在最后一个元素,存在的话赋值stoppedEvent,并发送next事件。否则发送complete事件

image.png

根据event事件进行判断.只有我们发送complete事件才能到next事件

image.png

dispatch中调用事件回调,这里先调用我们next事件,之后调用complete事件

image.png

  • 小结

对于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事件 打印结果

image.png

  • 分析

image.png

其实就是对BehaviorSubject的封装,不能发送error和complete事件,同时可以获取发送的value

image.png

当发送的时候使用accept替代我们的onNext(event)

4. 总结

对于我们的subject类来说,它既可以发送事件也能订阅,极大的方便了我们的开发。根据我们实际开发需要进行选择。

猜你喜欢

转载自juejin.im/post/7086817873494016030