RxSwift中的subject懊烤,subject是observable和Observer之間的橋梁梯醒,一個subject既是一個obserable也是一個observe,它既可以發(fā)出事件也可以監(jiān)聽事件
1.publicSubject:訂閱publicSubject時腌紧,只能接收到訂閱他之后發(fā)生的事件茸习,subject.onNext()發(fā)出onNext事件,對應(yīng)的還有onError()和onComplete()事件
2.replaySubject:訂閱replaySubject時壁肋,可以接收到訂閱他之后的事件逮光,但也可以接受訂閱他之前發(fā)出的事件,接受幾個事件取決于bufferSize的大小
3.behaviorSubject:訂閱behaviorSubject,可以接收到訂閱之前的最后一個事件墩划,這個在tableView中用的比較多涕刚,一般就是初始化數(shù)據(jù)顯示空值。
1乙帮,Subjects 基本介紹
(1)Subjects
既是訂閱者杜漠,也是 Observable
:
- 說它是訂閱者,是因為它能夠動態(tài)地接收新的值。
- 說它又是一個
Observable
驾茴,是因為當(dāng)Subjects
有了新的值之后盼樟,就會通過Event
將新值發(fā)出給他的所有訂閱者。
(2)一共有四種 Subjects
锈至,分別為:PublishSubject
晨缴、BehaviorSubject
、ReplaySubject
峡捡、Variable
击碗。他們之間既有各自的特點(diǎn),也有相同之處:
- 首先他們都是
Observable
们拙,他們的訂閱者都能收到他們發(fā)出的新的Event
稍途。 - 直到
Subject
發(fā)出.complete
或者.error
的Event
后,該Subject
便終結(jié)了砚婆,同時它也就不會再發(fā)出.next
事件械拍。 - 對于那些在
Subject
終結(jié)后再訂閱他的訂閱者,也能收到subject
發(fā)出的一條.complete
或.error
的event
装盯,告訴這個新的訂閱者它已經(jīng)終結(jié)了坷虑。 - 他們之間最大的區(qū)別只是在于:當(dāng)一個新的訂閱者剛訂閱它的時候,能不能收到
Subject
以前發(fā)出過的舊Event
埂奈,如果能的話又能收到多少個迄损。
(3)Subject 常用的幾個方法:
-
onNext(:):是
on(.next(:))
的簡便寫法。該方法相當(dāng)于subject
接收到一個.next
事件挥转。 -
onError(:):是
on(.error(:))
的簡便寫法。該方法相當(dāng)于subject
接收到一個.error
事件共屈。 -
onCompleted():是
on(.completed)
的簡便寫法绑谣。該方法相當(dāng)于subject
接收到一個.completed
事件。
2拗引,PublishSubject
(1)基本介紹
-
PublishSubject
是最普通的Subject
借宵,它不需要初始值就能創(chuàng)建。 -
PublishSubject
的訂閱者從他們開始訂閱的時間點(diǎn)起矾削,可以收到訂閱后Subject
發(fā)出的新Event
壤玫,而不會收到他們在訂閱前已發(fā)出的Event
。
(2)時序圖
- 最上面一條是
PublishSubject
哼凯。 - 下面兩條分別表示兩個新的訂閱欲间,它們訂閱的時間點(diǎn)不同,可以發(fā)現(xiàn)
PublishSubject
的訂閱者只能收到他們訂閱后的Event
断部。
(3)使用樣例
let disposeBag = DisposeBag()
//創(chuàng)建一個PublishSubject
let subject = PublishSubject<String>()
//由于當(dāng)前沒有任何訂閱者猎贴,所以這條信息不會輸出到控制臺
subject.onNext("111")
//第1次訂閱subject
subject.subscribe(onNext: { string in
print("第1次訂閱:", string)
}, onCompleted:{
print("第1次訂閱:onCompleted")
}).disposed(by: disposeBag)
//當(dāng)前有1個訂閱,則該信息會輸出到控制臺
subject.onNext("222")
//第2次訂閱subject
subject.subscribe(onNext: { string in
print("第2次訂閱:", string)
}, onCompleted:{
print("第2次訂閱:onCompleted")
}).disposed(by: disposeBag)
//當(dāng)前有2個訂閱,則該信息會輸出到控制臺
subject.onNext("333")
//讓subject結(jié)束
subject.onCompleted()
//subject完成后會發(fā)出.next事件了她渴。
subject.onNext("444")
//subject完成后它的所有訂閱(包括結(jié)束后的訂閱)达址,都能收到subject的.completed事件,
subject.subscribe(onNext: { string in
print("第3次訂閱:", string)
}, onCompleted:{
print("第3次訂閱:onCompleted")
}).disposed(by: disposeBag)
運(yùn)行結(jié)果如下:
3趁耗,BehaviorSubject
(1)基本介紹
-
BehaviorSubject
需要通過一個默認(rèn)初始值來創(chuàng)建沉唠。 - 當(dāng)一個訂閱者來訂閱它的時候,這個訂閱者會立即收到
BehaviorSubjects
上一個發(fā)出的event
苛败。之后就跟正常的情況一樣满葛,它也會接收到BehaviorSubject
之后發(fā)出的新的event
。
(2)時序圖
- 最上面一條是
BehaviorSubject
著拭。 - 下面兩條分別表示兩個新的訂閱纱扭,它們訂閱的時間點(diǎn)不同,可以發(fā)現(xiàn)
BehaviorSubject
的訂閱者一開始就能收到BehaviorSubjects
之前發(fā)出的一個Event
儡遮。
]
(3)使用樣例
let disposeBag = DisposeBag()
//創(chuàng)建一個BehaviorSubject
let subject = BehaviorSubject(value: "111")
//第1次訂閱subject
subject.subscribe { event in
print("第1次訂閱:", event)
}.disposed(by: disposeBag)
//發(fā)送next事件
subject.onNext("222")
//發(fā)送error事件
subject.onError(NSError(domain: "local", code: 0, userInfo: nil))
//第2次訂閱subject
subject.subscribe { event in
print("第2次訂閱:", event)
}.disposed(by: disposeBag)
運(yùn)行結(jié)果如下:
4乳蛾,ReplaySubject
(1)基本介紹
-
ReplaySubject
在創(chuàng)建時候需要設(shè)置一個bufferSize
,表示它對于它發(fā)送過的event
的緩存?zhèn)€數(shù)鄙币。 - 比如一個
ReplaySubject
的bufferSize
設(shè)置為 2肃叶,它發(fā)出了 3 個.next
的event
,那么它會將后兩個(最近的兩個)event
給緩存起來十嘿。此時如果有一個subscriber
訂閱了這個ReplaySubject
因惭,那么這個subscriber
就會立即收到前面緩存的兩個.next
的event
。 - 如果一個
subscriber
訂閱已經(jīng)結(jié)束的ReplaySubject
绩衷,除了會收到緩存的.next
的event
外蹦魔,還會收到那個終結(jié)的.error
或者.complete
的event
。
(2)時序圖
- 最上面一條是
ReplaySubject
(bufferSize
設(shè)為為 2)咳燕。 - 下面兩條分別表示兩個新的訂閱勿决,它們訂閱的時間點(diǎn)不同≌忻ぃ可以發(fā)現(xiàn)
ReplaySubject
的訂閱者一開始就能收到ReplaySubject
之前發(fā)出的兩個Event
(如果有的話)低缩。
(3)使用樣例
let disposeBag = DisposeBag()
//創(chuàng)建一個bufferSize為2的ReplaySubject
let subject = ReplaySubject<String>.create(bufferSize: 2)
//連續(xù)發(fā)送3個next事件
subject.onNext("111")
subject.onNext("222")
subject.onNext("333")
//第1次訂閱subject
subject.subscribe { event in
print("第1次訂閱:", event)
}.disposed(by: disposeBag)
//再發(fā)送1個next事件
subject.onNext("444")
//第2次訂閱subject
subject.subscribe { event in
print("第2次訂閱:", event)
}.disposed(by: disposeBag)
//讓subject結(jié)束
subject.onCompleted()
//第3次訂閱subject
subject.subscribe { event in
print("第3次訂閱:", event)
}.disposed(by: disposeBag)
運(yùn)行結(jié)果如下:
5,Variable
(1)基本介紹
-
Variable
其實就是對BehaviorSubject
的封裝曹货,所以它也必須要通過一個默認(rèn)的初始值進(jìn)行創(chuàng)建咆繁。 -
Variable
具有BehaviorSubject
的功能,能夠向它的訂閱者發(fā)出上一個event
以及之后新創(chuàng)建的event
顶籽。 - 不同的是玩般,
Variable
還會把當(dāng)前發(fā)出的值保存為自己的狀態(tài)。同時它會在銷毀時自動發(fā)送.complete
的event
礼饱,不需要也不能手動給Variables
發(fā)送completed
或者error
事件來結(jié)束它壤短。 - 簡單地說就是
Variable
有一個value
屬性设拟,我們改變這個value
屬性的值就相當(dāng)于調(diào)用一般Subjects
的onNext()
方法,而這個最新的onNext()
的值就被保存在value
屬性里了久脯,直到我們再次修改它纳胧。
注意:
Variables
本身沒有subscribe()
方法,但是所有Subjects
都有一個asObservable()
方法帘撰。我們可以使用這個方法返回這個Variable
的Observable
類型跑慕,拿到這個Observable
類型我們就能訂閱它了。
(2)使用樣例
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let disposeBag = DisposeBag()
//創(chuàng)建一個初始值為111的Variable
let variable = Variable("111")
//修改value值
variable.value = "222"
//第1次訂閱
variable.asObservable().subscribe {
print("第1次訂閱:", $0)
}.disposed(by: disposeBag)
//修改value值
variable.value = "333"
//第2次訂閱
variable.asObservable().subscribe {
print("第2次訂閱:", $0)
}.disposed(by: disposeBag)
//修改value值
variable.value = "444"
}
}
運(yùn)行結(jié)果如下:
注意:由于
Variable
對象在viewDidLoad()
方法內(nèi)初始化摧找,所以它的生命周期就被限制在該方法內(nèi)核行。當(dāng)這個方法執(zhí)行完畢后,這個Variable
對象就會被銷毀蹬耘,同時它也就自動地向它的所有訂閱者發(fā)出.completed
事件
作者:八級大狂風(fēng)AM
鏈接:http://www.reibang.com/p/def6965b0475