美文网首页
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