在我們?nèi)粘i_發(fā)中析命,有一些既可是Observable
又可是Observer
匙姜。舉個(gè)??:
let observable = textField.rx.text
observable.subscribe(onNext: { text in show(text: text) })
在這行代碼中毛秘,textField
當(dāng)前文本就是一個(gè)Observable
颅和,當(dāng)用戶在textField
中輸入時(shí),就會(huì)show
文本內(nèi)容茎辐。
再舉個(gè)??:
let disposeBag = DisposeBag()
let observer = textField.rx.text
let observable = Observable<String>.just("A")
observable.bind(to: observer)
.disposed(by: disposeBag)
這個(gè)時(shí)候宪郊,屏幕上就會(huì)顯示:
這時(shí),
textField
的當(dāng)前文本就是Observer
拖陆。此外弛槐,框架中還有一些輔助類型,既可是
Observable
又可是Observer
依啰。
1. AsyncSubject
AsyncSubject
將在Observable
產(chǎn)生完成事件后乎串,發(fā)出最后一個(gè)元素(僅僅只有最后一個(gè)元素)。如果Observable
沒有發(fā)出任何元素速警,只有一個(gè)完成事件叹誉,那AsyncSubject
也只有一個(gè)完成事件。如果Observable
因error
中止闷旧,那么AsyncSubject
只會(huì)將error
發(fā)送出來长豁,不會(huì)發(fā)出其它元素。
舉個(gè)??:
let disposeBag = DisposeBag()
//創(chuàng)建一個(gè)AsyncSubject
let subject = AsyncSubject<String>()
//訂閱subject
subject.subscribe{ print($0) }
.disposed(by: disposeBag)
subject.onNext("B")
subject.onNext("C")
subject.onNext("D")
subject.onCompleted()
這個(gè)時(shí)候輸出:
next(D)
completed
此時(shí)我們?cè)俑脑煲幌拢?/p>
let subject = AsyncSubject<String>()
subject.subscribe{ print($0) }
.disposed(by: disposeBag)
subject.onNext("B")
subject.onNext("C")
subject.onNext("D")
//SubjectError 自己定義的enum Error
subject.onError(SubjectError.error)
就會(huì)輸出:
error(error)
2. PublishSubject
PublishSubject
是將對(duì)觀察者發(fā)送訂閱后產(chǎn)生的元素
忙灼,而在訂閱前發(fā)出的元素將不會(huì)發(fā)送給觀察者匠襟。
-
PublishSubject
是最普通的Subject
,它不需要初始值就能創(chuàng)建 -
PublishSubject
的訂閱者從他們開始訂閱的時(shí)間點(diǎn)起该园,可以收到訂閱后Subject
發(fā)出的新Event
酸舍,而不會(huì)收到他們?cè)谟嗛喦耙寻l(fā)出的Event
舉個(gè)??:
let disposeBag = DisposeBag()
let subject = PublishSubject<String>()
//由于當(dāng)前沒有訂閱,所以不輸出
subject.onNext("??")
//第一次訂閱
subject.subscribe(onNext: { (element) in
print("第一次訂閱:\(element)")
}, onCompleted: {
print("completed")
}).disposed(by: disposeBag)
//當(dāng)前有一個(gè)訂閱爬范,輸出
subject.onNext("??")
//第二次訂閱
subject.subscribe(onNext: { (element) in
print("第二次訂閱:\(element)")
}, onCompleted: {
print("completed")
}).disposed(by: disposeBag)
//當(dāng)前有兩個(gè)訂閱 輸出
subject.onNext("??")
//結(jié)束subject
subject.onCompleted()
//再次發(fā)出.next事件
subject.onNext("??")
顯示如下:
第一次訂閱:??
第一次訂閱:??
第二次訂閱:??
第一次訂閱:completed
第二次訂閱:completed
第三次訂閱:completed
3. ReplaySubject
ReplaySubject
將對(duì)觀察者發(fā)送全部的元素父腕,無論觀察者是何時(shí)進(jìn)行訂閱的。這里存在多個(gè)版本的ReplaySubject
青瀑,有的只會(huì)將最新的n個(gè)元素發(fā)送給觀察者,有的只會(huì)將限制時(shí)間段內(nèi)最新的元素發(fā)送給觀察者萧诫。如果把ReplaySubject
當(dāng)作觀察者來使用斥难,注意不要在多個(gè)線程調(diào)用onNext
,onError
或onCompleted
。這樣會(huì)導(dǎo)致無序調(diào)用帘饶,將造成意想不到的結(jié)果哑诊。
-
ReplaySubject
在創(chuàng)建時(shí)候需要設(shè)置一個(gè)bufferSize
,表示它對(duì)于它發(fā)送過的event
的緩存?zhèn)€數(shù) - 比如一個(gè)
ReplaySubject
的bufferSize
設(shè)置為 2及刻,它發(fā)出了 3 個(gè).next
的event
镀裤,那么它會(huì)將后兩個(gè)(最近的兩個(gè))event
給緩存起來竞阐。此時(shí)如果有一個(gè)subscriber
訂閱了這個(gè)ReplaySubject
,那么這個(gè)subscriber
就會(huì)立即收到前面緩存的兩個(gè).next
的event
- 如果一個(gè)
subscriber
訂閱已經(jīng)結(jié)束的ReplaySubject
暑劝,除了會(huì)收到緩存的.next
的event
外骆莹,還會(huì)收到那個(gè)終結(jié)的.error
或者.complete
的event
舉個(gè)??:
let disposeBag = DisposeBag()
//創(chuàng)建
let subject = ReplaySubject<String>.create(bufferSize: 0)
//第1次訂閱subject
subject.subscribe{ print("第一次訂閱:\($0)") }
.disposed(by: disposeBag)
//發(fā)送.next事件
subject.onNext("A")
subject.onNext("B")
//第二次訂閱
subject.subscribe{ print("第二次訂閱:\($0)" )}
.disposed(by: disposeBag)
//發(fā)送.next事件
subject.onNext("C")
subject.onNext("D")
輸出結(jié)果:
第一次訂閱:next(A)
第一次訂閱:next(B)
第一次訂閱:next(C)
第二次訂閱:next(C)
第一次訂閱:next(D)
第二次訂閱:next(D)
當(dāng)bufferSize
改成1時(shí),結(jié)果就變成了:
第一次訂閱:next(A)
第一次訂閱:next(B)
第二次訂閱:next(B)
第一次訂閱:next(C)
第二次訂閱:next(C)
第一次訂閱:next(D)
第二次訂閱:next(D)
如果是2的話担猛,結(jié)果就變成了:
第一次訂閱:next(A)
第一次訂閱:next(B)
第二次訂閱:next(A)
第二次訂閱:next(B)
第一次訂閱:next(C)
第二次訂閱:next(C)
第一次訂閱:next(D)
第二次訂閱:next(D)
4. BehaviorSubject
BehaviorSubject
會(huì)把Observable
最新元素發(fā)出來(如果不存在最新的元素幕垦,就發(fā)出默認(rèn)元素)。然后將隨后產(chǎn)生的元素發(fā)送出來傅联。如果Observable
因?yàn)?code>error事件而中止先改,則不會(huì)發(fā)出任何元素,將error
事件發(fā)出來蒸走。
-
BehaviorSubject
需要通過一個(gè)默認(rèn)初始值來創(chuàng)建 - 當(dāng)一個(gè)訂閱者來訂閱它的時(shí)候仇奶,這個(gè)訂閱者會(huì)立即收到
BehaviorSubjects
上一個(gè)發(fā)出的event
。之后就跟正常的情況一樣比驻,它也會(huì)接收到BehaviorSubject
之后發(fā)出的新的event
舉個(gè)??:
let disposeBag = DisposeBag()
//創(chuàng)建一個(gè)BehaviorSubject
let subject = BehaviorSubject.init(value: "??")
//第一次訂閱
subject.subscribe{ print("第一次訂閱:\($0)") }
.disposed(by: disposeBag)
//發(fā)送.next事件
subject.onNext("??")
//發(fā)送error事件
subject.onError(NSError(domain: "local", code: 0, userInfo: nil))
//第二次訂閱
subject.subscribe{ print("第二次訂閱:\($0)") }
.disposed(by: disposeBag)
輸出結(jié)果:
第一次訂閱:next(??)
第一次訂閱:next(??)
第一次訂閱:error(Error Domain=local Code=0 "(null)")
第二次訂閱:error(Error Domain=local Code=0 "(null)")
4. Variable
在RxSwift
中猜嘱,Variable
相當(dāng)于Swift
中的var
。
-
Variable
其實(shí)就是對(duì)BehaviorSubject
的封裝嫁艇,所以它也必須要通過一個(gè)默認(rèn)的初始值進(jìn)行創(chuàng)建朗伶。 -
Variable
具有BehaviorSubject
的功能,能夠向它的訂閱者發(fā)出上一個(gè)event
以及之后新創(chuàng)建的event
步咪。 - 不同的是论皆,
Variable
還會(huì)把當(dāng)前發(fā)出的值保存為自己的狀態(tài)。同時(shí)它會(huì)在銷毀時(shí)自動(dòng)發(fā)送.complete
的event
猾漫,不需要也不能手動(dòng)給Variables
發(fā)送completed
或者error
事件來結(jié)束它点晴。 - 簡(jiǎn)單地說就是
Variable
有一個(gè)value
屬性,我們改變這個(gè)value
屬性的值就相當(dāng)于調(diào)用一般Subjects
的onNext()
方法悯周,而這個(gè)最新的onNext()
的值就被保存在value
屬性里了粒督,直到我們?cè)俅涡薷乃?/li> -
Variables
本身沒有subscribe()
方法,但是所有Subjects
都有一個(gè)asObservable()
方法禽翼。我們可以使用這個(gè)方法返回這個(gè)Variable
的Observable
類型屠橄,拿到這個(gè)Observable
類型我們就能訂閱它了。
舉個(gè)??:
let disposeBag = DisposeBag()
let variable = Variable.init("A")
variable.value = "B"
//第一次訂閱
variable.asObservable().subscribe{ print("第一次訂閱:\($0)") }
.disposed(by: disposeBag)
//修改value
variable.value = "C"
//第二次訂閱
variable.asObservable().subscribe{ print("第二次訂閱:\($0)") }
.disposed(by: disposeBag)
//修改value
variable.value = "D"
結(jié)果如下:
第一次訂閱:next(B)
第一次訂閱:next(C)
第二次訂閱:next(C)
第一次訂閱:next(D)
第二次訂閱:next(D)
第一次訂閱:completed
第二次訂閱:completed