美文网首页
RxSwift-subject使用

RxSwift-subject使用

作者: May_Dobin | 来源:发表于2019-08-06 10:44 被阅读0次

    Subject 主要包括以下几类

    • PublishSubject
    • BehaviorSubject
    • ReplaySubject
    • AsyncSubject
    • Variable
    • BehaviorRelay
      通过源码可以看出,他们有共同的父类,ObservableObserverType,表示他们既是序列,也是订阅者
    public final class PublishSubject<Element>
        : Observable<Element>
        , SubjectType
        , Cancelable
        , ObserverType
        , SynchronizedUnsubscribeType {}
    
    public final class BehaviorSubject<Element>
        : Observable<Element>
        , SubjectType
        , ObserverType
        , SynchronizedUnsubscribeType
        , Cancelable {}
    
    public class ReplaySubject<Element>
        : Observable<Element>
        , SubjectType
        , ObserverType
        , Disposable {}
    
    public final class AsyncSubject<Element>
        : Observable<Element>
        , SubjectType
        , ObserverType
        , SynchronizedUnsubscribeType{}
    
    public final class Variable<Element> {
    
        public typealias E = Element
    
        private let _subject: BehaviorSubject<Element>
    

    接下来介绍各自的特性和用法:

    PublishSubject

    • 在订阅序列之前,发送的信号,不会响应
    • 在订阅序列之后,发送的信号,接收响应
    //初始化一个PublishSubject ,Int类型的序列
     let publishSub = PublishSubject<Int>() 
            // 2:发送响应序列
            publishSub.onNext(1)
            // 3:订阅序列
            publishSub.subscribe { print("订阅到了:",$0)}
                .disposed(by: disposbag)
            // 再次发送响应
            publishSub.onNext(2)
            publishSub.onNext(3)
    

    根据PublishSubject的特性,publishSub.onNext(1)不会响应,所以运行结果如下:

    订阅到了: next(2)
    订阅到了: next(3)
    

    BehaviorSubject

    • BehaviorSubject 初始化有一个默认值。最终会响应observer.on(.next(self._element))
    • 开始收到订阅的时候,订阅者会收到 BehaviorSubject 上一个发出的event事件,如果此时,没有任何事件,发出初始化传入的默认值
      public init(value: Element) { self._element = value}
    • 收到新的onNext()事件,会调用
            case .next(let element):
                self._element = element
    

    重新赋值self._element,保存新的事件。

           // 1:创建序列
            let behaviorSub = BehaviorSubject.init(value: 100)
            behaviorSub.subscribe{ print("第一次订阅到了:",$0)}
                .disposed(by: disposbag)
            // 2:发送信号
            behaviorSub.onNext(2)
            behaviorSub.onNext(3)
            // 3:订阅序列
            behaviorSub.subscribe{ print("第二次订阅到了:",$0)}
                .disposed(by: disposbag)
            // 再次发送
            behaviorSub.onNext(4)
            behaviorSub.onNext(5)
            // 再次订阅
            behaviorSub.subscribe{ print("第三次订阅到了:",$0)}
                .disposed(by: disposbag)
    

    根据BehaviorSubject的特性,运行结果:

    //当前只有一个订阅者
    第一次订阅到了: next(100)
    第一次订阅到了: next(2)
    //当前有两个订阅者
    第一次订阅到了: next(3)
    第二次订阅到了: next(3)
    第一次订阅到了: next(4)
    第二次订阅到了: next(4)
    //当前有三个订阅者,依次打印
    第一次订阅到了: next(5)
    第二次订阅到了: next(5)
    第三次订阅到了: next(5)
    

    ReplaySubject

    • 不关心是否已经有订阅者,默认发送所有事件
    • 初始化一个最大缓存数bufferSize,保存订阅前最后发送的bufferSize个事件,收到订阅,开始响应;
    • 订阅后,常规操作,有新事件发送就开始响应,接下来看demo
     // 1:创建序列
            let replaySub = ReplaySubject<Int>.create(bufferSize: 2)
            // let replaySub = ReplaySubject<Int>.createUnbounded()
    
            // 2:发送信号
            replaySub.onNext(1)
            replaySub.onNext(2)
            replaySub.onNext(3)
            replaySub.onNext(4)
    
            // 3:订阅序列
            replaySub.subscribe{ print("订阅到了:",$0)}
                .disposed(by: disposbag)
            // 再次发送
            replaySub.onNext(7)
            replaySub.onNext(8)
            replaySub.onNext(9)
    

    lldb调试分析,第一个订阅者响应订阅前,保存的两次事件,值分别为34

    运行结果:

    //响应订阅前保存的两个事件
    订阅到了: next(3)
    订阅到了: next(4)
    //订阅后,响应所有
    订阅到了: next(7)
    订阅到了: next(8)
    订阅到了: next(9)
    

    AsyncSubject

    • 在收到完成信号之前无论发出多少事件,只响应收到onCompleted()信号前,最后发送的一个事件
      接下来看demo
     // 1:创建序列
            let asynSub = AsyncSubject<Int>.init()
            // 2:发送信号
            asynSub.onNext(1)
            asynSub.onNext(2)
            // 3:订阅序列
            asynSub.subscribe{ print("订阅到了:",$0)}
                .disposed(by: disposbag)
            // 再次发送
            asynSub.onNext(3)
            asynSub.onNext(4)
            //asynSub.onError(NSError.init(domain: "errorInfo", code: 111111, userInfo: nil))
            asynSub.onCompleted()
    

    lldb调试,断点进入了在收到完成信号时,响应了最后一个保存的.onNext()事件

    运行结果如下

    订阅到了: next(4)
    订阅到了: completed
    

    BehaviorRelay

    • 替代Variable
    • 由于封装了BehaviorSubject,所以具有BehaviorSubject的特性:a.通过一个默认值初始化;b.保存订阅信号前的最后一个事件,进行响应
    • 没有onComplete()onError()功能

    运行demo如下

            //1:创建序列
            let behaviorSubject = BehaviorRelay(value: 11111)
            //2:订阅信号
            behaviorSubject.subscribe(onNext: { (num) in
                print("订阅到了数值:\(num)")
            }).disposed(by: disposbag)
            //3:发送信号
            behaviorSubject.accept(22222)
    

    运行结果

    订阅到了数值:11111
    订阅到了数值:22222
    

    以上就是subject的特性和用法;

    相关文章

      网友评论

          本文标题:RxSwift-subject使用

          本文链接:https://www.haomeiwen.com/subject/ntzmdctx.html