-
Subjects
1、Subjects 既是訂閱者消请,也是 Observable
2杂腰、一共有四種 Subjects复亏,分別為:PublishSubject趾娃、BehaviorSubject、ReplaySubject缔御、Variable抬闷。他們之間既有各自的特點,也有相同之處:
- 首先他們都是 Observable耕突,他們的訂閱者都能收到他們發(fā)出的新的 Event笤成。
- 直到 Subject 發(fā)出 .complete 或者 .error 的 Event 后,該 Subject 便終結了眷茁,同時它也就不會再發(fā)出 .next 事件炕泳。
- 對于那些在 Subject 終結后再訂閱他的訂閱者,也能收到 subject 發(fā)出的一條 .complete 或 .error 的 event上祈,告訴這個新的訂閱者它已經終結了培遵。
- 他們之間最大的區(qū)別只是在于:當一個新的訂閱者剛訂閱它的時候挣磨,能不能收到 Subject 以前發(fā)出過的舊 Event,如果能的話又能收到多少個荤懂。
3、Subject 常用的幾個方法:
- onNext(:):是 on(.next(:)) 的簡便寫法塘砸。該方法相當于 subject 接收到一個 .next 事件节仿。
- onError(:):是 on(.error(:)) 的簡便寫法。該方法相當于 subject 接收到一個 .error 事件掉蔬。
- onCompleted():是 on(.completed) 的簡便寫法廊宪。該方法相當于 subject 接收到一個 .completed 事件。
-
PublishSubject
PublishSubject 的訂閱者從他們開始訂閱的時間點起女轿,可以收到訂閱后 Subject 發(fā)出的新 Event箭启,而不會收到他們在訂閱前已發(fā)出的 Event
//創(chuàng)建一個PublishSubject
let subject = PublishSubject<String>()
//由于當前沒有任何訂閱者,所以這條信息不會輸出到控制臺
subject.onNext("111")
//第1次訂閱subject
subject.subscribe(onNext: { string in
print("第1次訂閱:", string)
}, onCompleted:{
print("第1次訂閱:onCompleted")
}).disposed(by: disposeBag)
-
BehaviorSubject
BehaviorSubject 需要通過一個默認初始值來創(chuàng)建
當一個訂閱者來訂閱它的時候蛉迹,這個訂閱者會立即收到 BehaviorSubjects 上一個 發(fā)出的 event傅寡。之后就跟正常的情況一樣,它也會接收到 BehaviorSubject 之后發(fā)出的新的 event
//創(chuàng)建一個BehaviorSubject
let subject = BehaviorSubject(value: "111")
//第1次訂閱subject
subject.subscribe { event in
print("第1次訂閱:", event)
}.disposed(by: disposeBag)
-
ReplaySubject
ReplaySubject 在創(chuàng)建時候需要設置一個 bufferSize北救,表示它對于它發(fā)送過的 event 的緩存?zhèn)€數(shù)
比如一個 ReplaySubject 的 bufferSize 設置為 2荐操,它發(fā)出了 3 個 .next 的 event,那么它會將后兩個(最近的兩個)event 給緩存起來珍策。此時如果有一個 subscriber 訂閱了這個 ReplaySubject托启,那么這個 subscriber 就會立即收到前面緩存的兩個 .next 的 event
如果一個 subscriber 訂閱已經結束的 ReplaySubject,除了會收到緩存的 .next 的 event 外攘宙,還會收到那個終結的 .error 或者 .complete 的 event
//創(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)
-
Variable
(注意:由于 Variable 在之后版本中將被廢棄屯耸,建議使用 Varible 的地方都改用下面介紹的 BehaviorRelay 作為替代)
Variable 其實就是對 BehaviorSubject 的封裝,所以它也必須要通過一個默認的初始值進行創(chuàng)建
Variable 具有 BehaviorSubject 的功能蹭劈,能夠向它的訂閱者發(fā)出上一個 event 以及之后新創(chuàng)建的 event
不同的是疗绣,Variable 還把會把當前發(fā)出的值保存為自己的狀態(tài)。同時它會在銷毀時自動發(fā)送 .complete 的 event铺韧,不需要也不能手動給 Variables 發(fā)送 completed 或者 error 事件來結束它
簡單地說就是 Variable 有一個 value 屬性持痰,我們改變這個 value 屬性的值就相當于調用一般 Subjects 的 onNext() 方法,而這個最新的 onNext() 的值就被保存在 value 屬性里了祟蚀,直到我們再次修改它
Variables 本身沒有 subscribe() 方法工窍,但是所有 Subjects 都有一個 asObservable() 方法。我們可以使用這個方法返回這個 Variable 的 Observable 類型前酿,拿到這個 Observable 類型我們就能訂閱它了患雏。
//創(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"
-
BehaviorRelay
BehaviorRelay 是作為 Variable 的替代者出現(xiàn)的。它的本質其實也是對 BehaviorSubject 的封裝罢维,所以它也必須要通過一個默認的初始值進行創(chuàng)建
BehaviorRelay 具有 BehaviorSubject 的功能淹仑,能夠向它的訂閱者發(fā)出上一個 event 以及之后新創(chuàng)建的 event
與 BehaviorSubject 不同的是,BehaviorRelay 會在銷毀時自動發(fā)送 .complete 的 event,不需要也不能手動給 BehaviorReply 發(fā)送 completed 或者 error 事件來結束它
BehaviorRelay 有一個 value 屬性匀借,我們通過這個屬性可以獲取最新值颜阐。而通過它的 accept() 方法可以對值進行修改
//創(chuàng)建一個初始值為111的BehaviorRelay
let subject = BehaviorRelay<String>(value: "111")
//修改value值
subject.accept("222")
//第1次訂閱
subject.asObservable().subscribe {
print("第1次訂閱:", $0)
}.disposed(by: disposeBag)
//修改value值
subject.accept("333")
如果想將新值合并到原值上,可以通過 accept() 方法與 value 屬性配合來實現(xiàn)吓肋。(這個常用在表格上拉加載功能上凳怨,BehaviorRelay 用來保存所有加載到的數(shù)據)
//創(chuàng)建一個初始值為包含一個元素的數(shù)組的BehaviorRelay
let subject = BehaviorRelay<[String]>(value: ["1"])
//修改value值
subject.accept(subject.value + ["2", "3"])
//第1次訂閱
subject.asObservable().subscribe {
print("第1次訂閱:", $0)
}.disposed(by: disposeBag)
//修改value值
subject.accept(subject.value + ["4", "5"])