RxSwift練習(xí):https://github.com/flywo/RxSwiftPractice
Subject
Subject既是被觀察者,又是觀察者。有如下四種類(lèi)型:
1.PublishSubject:只會(huì)發(fā)送最新的事件
2.BehaviorSubject:發(fā)送訂閱前一次事件或初始化事件以和后續(xù)事件
3.ReplaySubject:發(fā)送訂閱前指定緩存的事件
4.Variable:BehaviorSubject的封裝
PublishSubject
//創(chuàng)建主題
let subject = PublishSubject<String>()
//發(fā)布事件,此時(shí)不會(huì)有任何反應(yīng),因?yàn)闆](méi)人訂閱該主題
subject.onNext("1")
//訂閱主題,此時(shí)也不會(huì)有任何反應(yīng),因?yàn)榘l(fā)布事件在訂閱主題前面
let subscriptionOne = subject.subscribe {print($0)}
//此時(shí)發(fā)布事件,就有反應(yīng)了
subject.onNext("2")
////PublishSubject////
let subscriptionTwo = subject.subscribe { event in
print("2", event.element ?? event)
}
subject.onNext("3")
//停止訂閱one
subscriptionOne.dispose()
//此時(shí)不會(huì)再有one的打印
subject.onNext("4")
//一旦發(fā)送了completed/error等stop事件,則后續(xù)next事件不會(huì)再次發(fā)送,但是會(huì)繼續(xù)發(fā)送重復(fù)發(fā)送停止事件,即completed/error事件
subject.onCompleted()
subject.onNext("5")
subscriptionTwo.dispose()
let disposeBag = DisposeBag()
subject.subscribe {
print("3", $0.element ?? $0)
}.disposed(by: disposeBag)
subject.onNext("?")
執(zhí)行結(jié)果如下:
next(2)
next(3)
2 3
2 4
2 completed
3 completed
需要注意的點(diǎn):
1.發(fā)送.completed事件,會(huì)終止被觀察者隊(duì)列
2.即使給隊(duì)列添加新的訂閱,任然不會(huì)發(fā)送.next事件,因?yàn)殛?duì)列已經(jīng)被終止
3.使用完畢后,一定記得取消訂閱
4.即使被終止了,不會(huì)發(fā)送后續(xù).next事件,但是終止的completed事件還是會(huì)發(fā)送
BehaviorSubject
enum MyError: Error {
case anError
}
func customPrint<T: CustomStringConvertible>(label: String, event: Event<T>) {
//打印元素,如果不存在就打印錯(cuò)誤,如果不存在就打印事件
print(label, event.element ?? event.error ?? event)
}
//由于會(huì)發(fā)送上一次事件,所以必須要初始化
let subject = BehaviorSubject(value: "Initial value")
let disposeBag = DisposeBag()
subject.onNext("X")
//會(huì)將X打印出來(lái)
subject.subscribe {
customPrint(label: "1->", event: $0)
}.disposed(by: disposeBag)
subject.onNext("Y")
subject.onError(MyError.anError)
subject.subscribe {
customPrint(label: "2->", event: $0)
}.disposed(by: disposeBag)
subject.onNext("Z")
打印:
1-> X
1-> Y
1-> anError
2-> anError
ReplaySubject
//指定了buffer為2
let subject = ReplaySubject<String>.create(bufferSize: 2)
let disposeBag = DisposeBag()
subject.onNext("1")
subject.onNext("2")
subject.onNext("3")
subject.subscribe {
customPrint(label: "1->", event: $0)
}.disposed(by: disposeBag)
//1不會(huì)被打印,因?yàn)橐呀?jīng)超過(guò)了buffer
subject.subscribe {
customPrint(label: "2->", event: $0)
}.disposed(by: disposeBag)
subject.onNext("4")
subject.onError(MyError.anError)
//添加錯(cuò)誤,依舊會(huì)返回上兩個(gè)事件
// subject.dispose()一般來(lái)說(shuō),不需要主動(dòng)銷(xiāo)毀訂閱,讓其自動(dòng)管理就好
subject.subscribe {
customPrint(label: "3->", event: $0)
}.disposed(by: disposeBag)
打印:
1-> 2
1-> 3
2-> 2
2-> 3
1-> 4
2-> 4
1-> anError
2-> anError
3-> 3
3-> 4
3-> anError
Variable
//可以明確類(lèi)型Variable<String>("")
let variable = Variable("Initial value")
let disposeBag = DisposeBag()
//對(duì)value進(jìn)行賦值,則等價(jià)于調(diào)用了onNext
variable.value = "New initial value"
//通過(guò)asObservable可以獲得被封裝了的BehaviorSubject.
//不需要手動(dòng)的completed
variable.asObservable().subscribe {
customPrint(label: "1->", event: $0)
}.disposed(by: disposeBag)
//不能variable添加error和completed
variable.value = "1"
variable.asObservable().subscribe {
customPrint(label: "2->", event: $0)
}.disposed(by: disposeBag)
variable.value = "2"
打?。?/p>
1-> New initial value
1-> 1
2-> 1