【RXSwift】系列三 :Subject詳解

Subject介紹

  • Subject 既是 Observer 也是 Observable 。它可以訂閱一個(gè)或多個(gè) Observable,當(dāng)收到消息后進(jìn)行處理,也可以通過Event將數(shù)據(jù)發(fā)送給訂閱者。
  • 一共有四種Subject,PublishSubject、BehaviorSubject、ReplaySubject、BehaviorRelay、Variable(廢棄、用BehaviorRelay替代),他們最大區(qū)別在于:當(dāng)一個(gè)新的訂閱者訂閱它的時(shí)候,能否收到Subject以前發(fā)出過的就的Event,如果可以的會(huì),又能收到多少個(gè)
  1. PublishSubject

當(dāng)訂閱者訂閱PublishSubject 時(shí),只會(huì)收到訂閱后Subject發(fā)出的新Event,而不會(huì)收到訂閱之前發(fā)出的舊Event

    func publishSubject() {
        let subject = PublishSubject<String>()
        subject.onNext("A")     //不會(huì)收到
        subject.subscribe(onNext: { element in
            print("第1次訂閱:", element)
        }, onCompleted: {
            print("第1次訂閱:completed")
        }).disposed(by: bag)
        subject.onNext("B")     //1訂閱收到
        
        subject.subscribe(onNext: { element in
            print("第2次訂閱:", element)
        }, onCompleted: {
            print("第2次訂閱:completed")
        }).disposed(by: bag)
        
        subject.onNext("C")     //1、2訂閱會(huì)收到
        subject.onNext("D")     //1、2訂閱會(huì)收到
        subject.onCompleted()   //所有的訂閱都會(huì)收到
        subject.onNext("F")     //不會(huì)收到
        
        //subject完成后,所有的訂閱,包括完成后的訂閱,都會(huì)收到.completed事件
        subject.subscribe(onNext: { element in
            print("第3次訂閱:", element)
        }, onCompleted: {
            print("第3次訂閱:completed")
        }).disposed(by: bag)
    }

運(yùn)行結(jié)果:

第1次訂閱: B
第1次訂閱: C
第2次訂閱: C
第1次訂閱: D
第2次訂閱: D
第1次訂閱:completed
第2次訂閱:completed
第3次訂閱:completed
  1. BehaviorSubject

BehaviorSubject 通過一個(gè)默認(rèn)初始值來創(chuàng)建,當(dāng)訂閱者訂閱BehaviorSubject 時(shí),會(huì)收到訂閱后Subject上一個(gè)發(fā)出的Event,如果還沒有收到任何數(shù)據(jù),會(huì)發(fā)出一個(gè)默認(rèn)值。之后就和PublishSubject 一樣,正常接收新的事件。

    func behaviorSubject() {
        let subject = BehaviorSubject(value: "A")
        subject.subscribe(onNext: { element in
            print("第1次訂閱:", element)
        }, onCompleted: {
            print("第1次訂閱:completed")
        }).disposed(by: bag)
        subject.onNext("B")
        
        subject.subscribe(onNext: { element in
            print("第2次訂閱:", element)
        }, onCompleted: {
            print("第2次訂閱:completed")
        }).disposed(by: bag)
        
        subject.onNext("C")     //1、2訂閱會(huì)收到
        subject.onNext("D")     //1、2訂閱會(huì)收到
        subject.onCompleted()   //所有的訂閱都會(huì)收到
        subject.onNext("F")     //不會(huì)收到
        
        //subject完成后,所有的訂閱,包括完成后的訂閱,都會(huì)收到.completed事件
        subject.subscribe(onNext: { element in
            print("第3次訂閱:", element)
        }, onCompleted: {
            print("第3次訂閱:completed")
        }).disposed(by: bag)
    }

運(yùn)行結(jié)果:

第1次訂閱: A
第1次訂閱: B
第2次訂閱: B
第1次訂閱: C
第2次訂閱: C
第1次訂閱: D
第2次訂閱: D
第1次訂閱:completed
第2次訂閱:completed
第3次訂閱:completed
  1. ReplaySubject

ReplaySubject 創(chuàng)建的時(shí)候需要設(shè)置一個(gè) buffSize,用來表示發(fā)出過的Event的緩存?zhèn)€數(shù)。當(dāng)一個(gè)訂閱者訂閱了一個(gè) ReplaySubject 之后,他將會(huì)收到當(dāng)前緩存在 buffer 中的數(shù)據(jù)和這之后產(chǎn)生的新數(shù)據(jù)。如果訂閱者訂閱了一個(gè)已經(jīng)結(jié)束的ReplaySubject,除了會(huì)收到緩存中的 next 的Event,還會(huì)收到那個(gè)終結(jié)的 error或 completed 的Event

    func replaySubject() {
        let subject = ReplaySubject<String>.create(bufferSize: 2)
        subject.subscribe(onNext: { element in
            print("第1次訂閱:", element)
        }, onCompleted: {
            print("第1次訂閱:completed")
        }).disposed(by: bag)
        subject.onNext("A")
        subject.onNext("B")
        
        subject.subscribe(onNext: { element in
            print("第2次訂閱:", element)
        }, onCompleted: {
            print("第2次訂閱:completed")
        }).disposed(by: bag)
        
        subject.onNext("C")
        subject.onCompleted()
        subject.onNext("D")     //不會(huì)收到
        
        //subject完成后,所有的訂閱,包括完成后的訂閱,都會(huì)收到.completed事件
        subject.subscribe(onNext: { element in
            print("第3次訂閱:", element)
        }, onCompleted: {
            print("第3次訂閱:completed")
        }).disposed(by: bag)
    }

運(yùn)行結(jié)果:

第1次訂閱: A
第1次訂閱: B
第2次訂閱: A
第2次訂閱: B
第1次訂閱: C
第2次訂閱: C
第1次訂閱:completed
第2次訂閱:completed
第3次訂閱: B
第3次訂閱: C
第3次訂閱:completed
  1. Variable (deprecated)

Variable 封裝了 BehaviorSubject。使用 variable 的好處是 variable 將不會(huì)顯式的發(fā)送 Error 或者 Completed。在 deallocated 的時(shí)候,Variable 會(huì)自動(dòng)的發(fā)送 complete 事件。

使用Variable的時(shí)候會(huì)打印提示:Variable is planned for future deprecation. Please consider BehaviorRelay as a replacement

    func variable() {
        let variable = Variable("A")
        variable.asObservable().subscribe(onNext: { element in
            print("第1次訂閱:", element)
        }, onCompleted: {
            print("第1次訂閱:completed")
        }).disposed(by: bag)
        
        variable.value = "B"
        variable.asObservable().subscribe(onNext: { element in
            print("第2次訂閱:", element)
        }, onCompleted: {
            print("第2次訂閱:completed")
        }).disposed(by: bag)
        
        variable.value = "C"
    }

運(yùn)行結(jié)果:

第1次訂閱: A
第1次訂閱: B
第2次訂閱: B
第1次訂閱: C
第2次訂閱: C
第1次訂閱:completed
第2次訂閱:completed
  1. BehaviorRelay

BehaviorRelay 作為Variable 的替代者出現(xiàn),本質(zhì)上也是對(duì)BehaviorSubject的封裝。不同的是Variable他不是觀察者也不是序列,沒有任何繼承。 BehaviorRelay 只遵守 ObservableType協(xié)議,所以它其實(shí)是一個(gè)序列,但它有一個(gè)value 屬性,通過這屬性能拿到最新的值。而通過它的 accept() 方法可以對(duì)值進(jìn)行修改,通過它里面的subject將修改的值發(fā)送出去。

    func behaviorRelay() {
        let subject = BehaviorRelay(value: "A")
        subject.asObservable().subscribe(onNext: { element in
            print("第1次訂閱:", element)
        }, onCompleted: {
            print("第1次訂閱:completed")
        }).disposed(by: bag)
        
        subject.accept("B")
        subject.asObservable().subscribe(onNext: { element in
            print("第2次訂閱:", element)
        }, onCompleted: {
            print("第2次訂閱:completed")
        }).disposed(by: bag)
        
        subject.accept("C")
    }

運(yùn)行結(jié)果:

第1次訂閱: A
第1次訂閱: B
第2次訂閱: B
第1次訂閱: C
第2次訂閱: C
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容