Rx
Rx是ReactiveX的縮寫,簡單來說就是基于異步事件序列的響應(yīng)式編程。
RxSiwft:他只是基于Swift語言的Rx標(biāo)準(zhǔn)實現(xiàn)接口庫,所以RxSwift里不包含任何Cocoa或者UI方面的類。
RxCocoa:是基于RxSwift針對于iOS開發(fā)的一個庫,他通過Extension的方法給原生的比如UI控件添加了Rx的特性,使得我們更容易訂閱和響應(yīng)這些控件。
Obsevable
·Observable<T>這個類就是Rx框架的基礎(chǔ),我們可以稱它為可觀察序列。它的作用就是可以異步的產(chǎn)生一系列的事件,即一個Observable<T>對象會隨著時間推移不定期的發(fā)出event(element: T)這樣一個東西。
·而且這些事件還可以攜帶數(shù)據(jù),他的泛型<T>就是用來指定這個事件攜帶的數(shù)據(jù)的類型。
·有了可觀察序列,我們還需要有一個Observer(訂閱者)來訂閱它這樣這個訂閱者才能收到Observable<T>不是發(fā)出的事件
可以看到事件就是一個枚舉,也就是說一個Observable是可以發(fā)出3種不同類型的事件(next,error, completed)
Observable的創(chuàng)建方法
1.just()該方法通過傳入一個默認(rèn)值來初始化
let observable = Observable<Int>.just(5)
2.of()該方法可以接受可變數(shù)量的參數(shù)(必須要是同類型的)
let observable = Observable.of("A", "B","C")
3.from()該方法需要一個數(shù)組參數(shù)
let observable = Observable.from(["A", "B","C"])
4.empty()該方法創(chuàng)建一個空內(nèi)容的Observable
let observable = Observable<Int>
5.never()該方法創(chuàng)建一個永遠(yuǎn)不會發(fā)出事件(也不會終止)的Observable序列
let observable = Observable<Int>.never()
6.error()該方法創(chuàng)建一個不做任何操作,而是直接發(fā)送一個錯誤的Observable序列
enum MyError: Error {
case A
case B
}
let observable = Observable<int>.error(MyError.A)
7.range()該方法通過指定起始和結(jié)束數(shù)值,創(chuàng)建一個以這個范圍內(nèi)所有值作為初始值的Observable序列
let observable = Observable.range(start: 1, count: 5)
let observable = Observable.of(1, 2, 3, 4, 5)
8.repeatElement()該方法創(chuàng)建一個可以無限發(fā)出給定元素的Event的Observable序列(永不終止)
let observable = Observable.repeatElement(1)
9.generate()該方法創(chuàng)建一個只有當(dāng)提供的所有的判斷條件都為真的時候,才會給出動作的Observable序列
let obsevable = Observable.generate(
initialState: 0,
condition: { $0 <= 10 },
iterate: { $0 + 2 }
)
let observable = Observable.of(0, 2, 4, 6, 8, 10)
10.create()該方法接受一個block形式的參數(shù),任務(wù)是對每一個過來的訂閱進(jìn)行處理
//這個block有一個回調(diào)參數(shù)observer就是訂閱這個Observable對象的訂閱者
//當(dāng)一個訂閱者訂閱這個Observable對象的時候,就會講經(jīng)樂者作為參數(shù)傳入這個block來執(zhí)行一些內(nèi)容
let observable = Observable<String>.create{ observer in
observer.onNext("Hello")
observer.onCompleted()
//因為一個訂閱行為會有一個Disposable類型的返回值,所以在結(jié)尾一定要return一個Disposable
return Disposables.create()
}
observable.subscribe {
print($0)
}
11.defferred()該方法相當(dāng)于創(chuàng)建一個Observable工廠,通過傳入一個block來執(zhí)行延遲Observable序列創(chuàng)建的行為,而這個block里就是真正的實例化序列對象的地方。
var isOdd = true
let factory: Observable<Int> = Observable.deferred {
isOdd = !isOdd
if isOdd {
return Observable.of(1, 3, 5, 7)
} else {
return Observable.of(2, 4, 6, 8)
}
}
factory.subscribe { event in
print("\(isOdd)", event)
}
factory.subscribe { event in
print("\(isOdd)", event)
}
12.interval()該方法創(chuàng)建的Observable序列每隔一段設(shè)定的時間,就發(fā)出一個索引數(shù)的元素。而且他會一直發(fā)送下去。
let observable = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
observable.subscribe { event in
print(event)
}
13.timer()
(1).這個方法有兩種用法,一種是創(chuàng)建的Observable序列在經(jīng)過設(shè)定的一段時間后,產(chǎn)生唯一的一個元素
// 5秒鐘后發(fā)出唯一的一個元素0
let observable = Observable<int>.timer(5, scheduler: MainScheduler.instance)
observable.subscribe { event in
print(event)
}
(2).另一種是創(chuàng)建的Observable序列在經(jīng)過設(shè)定的一段時間后,每隔一段時間產(chǎn)生一個元素
//延時5秒后,每隔1秒發(fā)出一個元素
let observable = Observable<Int>.timer(5, period: 1, scheduler:MainScheduler.instance)
observable.subscribe { event in
print(event)
}
訂閱Observable
用法一:
我們使用subscribe()訂閱了一個Observable對象,該方法的block的回調(diào)參數(shù)就是被發(fā)出的event事件
如果想要獲取到這個事件中的數(shù)據(jù),可以通過event,element得到
let observable = Observable.of(0, 2, 4, 6, 8, 10)
observable.subscribe { event in
print(event.element)
}
用法二:
RxSwift還提供了另一個subscribe方法。他可以吧event分類
let observable = Observable.of(0, 2, 4, 6, 8, 10)
observable.subscribe(onNext: { element in
print(element)
}, onError: { error in
print(error)
}, onCompleted: {
print("comepleted")
}, onDisposed: {
print("disposed")
})
監(jiān)聽事件的生命周期
doOn監(jiān)聽事件的生命周期
let observable = Observable.of(0, 2, 4, 6, 8, 10)
observable
doOn(onNext: { element in
print("Intercepted Next:", element)
}, onError: { error in
print("Intercepted Error:", error)
}, onCompleted: {
print("Intercepted comepleted")
}, onDisposed: {
print("Intercepted disposed")
})
.subscribe(onNext: { element in
print(element)
}, onError: { error in
print(error)
}, onCompleted: {
print("comepleted")
}, onDisposed: {
print("disposed")
})
Observable的銷毀(Dispose)
dispose()該方法可以手動取消一個訂閱行為
let observable = Observable.of(0, 2, 4, 6, 8, 10)
let subscription = observable.subscribe { event in
print(event)
}
subscription.dispose()
除了dispose()方法之外,我們更經(jīng)常用到的是一個叫DisposeBag的對象來管理多個訂閱行為的銷毀,他會在自己快要dealloc的時候,對它里面的所有訂閱行為都屌用dispose()
let disposeBag = DisposeBag()
let observable1 = Observable.of("A", "B", "C")
observable1.subscribe { event in
print(event)
}.disposed(by: disposeBag)
let observable2 = Observable.of(1, 2, 3)
observable2.subscribe { event in
print(event)
}.disposed(by: disposeBag)
觀察者(Observer)
觀察者的作用就是監(jiān)聽事件,然后對這個事件作出相應(yīng)。
1.在subscribe方法中創(chuàng)建
創(chuàng)建觀察者最直接的方法就是在Observable的subscribe方法后面描述當(dāng)事件發(fā)生時,需要如何做出響應(yīng)。
2.在bind方法中創(chuàng)建
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!
let disposeBag = DisposeBag()
override func viewDidLoad() {
let observable = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
observable
.map { "當(dāng)前縮陰術(shù):\($0)" }
.bind { [weak self](text) in
self?.label.text = text
}
.disposed(by: disposeBag)
}
}
使用AnyObserver創(chuàng)建觀察者
1.配合subscribe方法使用
let observer: AnyObserver<String> = AnyObserver { (event) in
switch event {
case .next(let data):
print(data)
case .error(let error):
print(error)
case .completed:
print("completed")
}
}
let observable = Observable.of("A", "B", "C")
observable.subscribe(observer)
2.配合bindTo使用
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!
let disposeBag = DisposeBag()
override func viewDidLoad() {
let observer: AnyObserver<String> = AnyObserver { [weak self] (event) in
switch event {
case .next(let text):
self?.label.text = text
default:
break
}
}
let observable = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
observable
.map { "當(dāng)前縮陰術(shù):\($0)" }
.bind(to: observer)
.disposed(by: disposeBag)
}
}
使用Binder創(chuàng)建觀察者
1.相較于AnyObserver的大而全,Binder更專注于特定的場景。Binder主要有以下兩個特征:
·不會處理錯誤事件
·確保綁定都是在給定Scheduler上執(zhí)行(默認(rèn)MainScheduler)
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!
let disposeBag = DisposeBag()
override func viewDidLoad() {
let observer: Binder<String> = Binder(label) { (view, text) in
view.text = text
}
let observable = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
observable
.map { "當(dāng)前縮陰術(shù):\($0)" }
.bind(to: observer)
.disposed(by: disposeBag)
}
}
自定義可綁定屬性
方式一:通過對UI類進(jìn)行擴(kuò)展
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!
let disposeBag = DisposeBag()
override func viewDidLoad() {
let observable = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
observable
.map { "當(dāng)前縮陰術(shù):\($0)" }
.bind(to: label.fontSize)
.disposed(by: disposeBag)
}
}
extension UILabel {
public var fontSize: Binder<CGFloat> {
return Binder(self) { label, fontSize in
label.font = UIFont.systemFont(ofSize: fontSize)
}
}
}
方式二:通過對Reactive類進(jìn)行擴(kuò)展
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!
let disposeBag = DisposeBag()
override func viewDidLoad() {
let observable = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
observable
.map { "當(dāng)前縮陰術(shù):\($0)" }
.bind(to: label.rx.fontSize)
.disposed(by: disposeBag)
}
}
extension Reactive where Base: UILabel {
public var fontSize: Binder<CGFloat> {
return Binder(self.base) { label, fontSize in
label.font = UIFont.systemFont(ofSize: fontSize)
}
}
}
Subjects
Subjects既是訂閱者,也是Observable
一共有四種Subjects,分別是PublishSubject,BehaviorSubject,ReplaySubject,Variable.她們之間最大的區(qū)別只是在于:當(dāng)一個新的訂閱者剛好訂閱它的時候,能不能收到Subject以前發(fā)出過的舊事件,如果能的話又能收到多少個。
PublishSubject
- PublishSubject不需要初始值就能創(chuàng)建
- PublishSubject的訂閱者從他們呢開始訂閱的時間點起,可以收到訂閱后Subject發(fā)出的新事件,而不會收到他們呢在訂閱前已發(fā)出的事件
let disposeBag = DisposeBag()
let subject = PublishSubject<String>()
subject.onNext("111")
subject.subscribe(onNext: { string in
print("第1次訂閱:", string)
}, onCompleted: {
print("第1次訂閱:onCompleted")
}).disposed(by: disposeBag)
subject.onNext("222")
subject.subscribe(onNext: { string in
print("第2次訂閱:", string)
}, onCompleted: {
print("第2次訂閱:onCompleted")
}).disposed(by: disposeBag)
subject.onNext("333")
subject.onCompleted()
subject.onNext("444")
subject.subscribe(onNext: { string in
print("第3次訂閱:", string)
}, onCompleted: {
print("第3次訂閱:onCompleted")
}).disposed(by: disposeBag)
BehaviorSubject
1.需要一個默認(rèn)初始值來創(chuàng)建
2.當(dāng)一個訂閱者來訂閱它的時候,這個訂閱者會立即收到BehaviorSubject上一個發(fā)出的事件。之后就跟正常的情況一樣,他也會接收到BehaviorSubject之后發(fā)出的新的事件
let disposeBag = DisposeBag()
let subject = BehaviorSubject(value: "111")
subject.subscrbe { event in
print("第1次訂閱:", event)
}.disposed(by: disposeBag)
subject.onNext("222")
subject.onError(NSError(domain: "local", code: 0, userInfo:nil))
subject.subscribe { event in
print("第2次訂閱:", event)
}.disposed(by: disposeBag)
ReplaySubject
ReplaySubject在創(chuàng)建時候需要設(shè)置一個bufferSize,表示他對于他發(fā)送過的事件的緩存?zhèn)€數(shù)。
如果一個subscriber訂閱已經(jīng)結(jié)束的ReplaySubject,除了會收到緩存的。next的事件外,還會收到那個終結(jié)的.error或者.complete的事件。
let disposeBag = DisposeBag()
let subject = ReplaySubject<String>.create(bufferSize: 2)
subject.onNext("111")
subject.onNext("222")
subject.onNext("333")
subject.subscribe { event in
print("第1次訂閱:", event)
}.disposed(by: disposeBag)
subject.onNext("444")
subject.subscribe { event in
print("第2次訂閱:", event)
}.disposed(by: disposeBag)
subject.onCompleted()
subject.subscribe { event in
print("第3次訂閱:", event)
}.disposed(by: disposeBag)
Variable
Variable其實就是對BehaviorSubject的封裝,所以他也必須要通過一個默認(rèn)的初始值進(jìn)行創(chuàng)建
不同的是,Variable還會把當(dāng)前發(fā)出的值保存為自己的狀態(tài)。同時他會在銷毀時自動發(fā)送.complete的事件,不需要也不能手動給Variables發(fā)送completed或者error事件來結(jié)束它
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let disposeBag = DisposeBag()
let variable = Variable("111")
variable.value = "222"
variable.asObservable().subscribe {
print("第1次訂閱:", $0)
}.disposed(by: disposeBag)
variable.value = "333"
variable.asObservable().subscribe {
print("第2次訂閱:", $0)
}.disposed(by: disposeBag)
variable.value = "444"
}
}
操作符
變換操作指的是對原始的Observable序列進(jìn)行一些轉(zhuǎn)換。
buffer 方法作用是緩沖組合,第一個參數(shù)是緩沖時間,第二個參數(shù)是緩沖個數(shù),第三個參數(shù)是線程
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
let subject = PublishSubject<String>()
//沒緩存3個元素則組合起來一起發(fā)出
//如果1秒鐘內(nèi)不夠3個也會發(fā)出(有幾個發(fā)幾個,一個都沒有發(fā)空數(shù)組[])
subject
.buffer(timeSpan: 1, count: 3, scheduler:MainScheduler.instance)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
subject.onNext("a")
subject.onNext("b")
subject.onNext("c")
subject.onNext("1")
subject.onNext("2")
subject.onNext("3")
}
}
window 操作符和buffer十分相識,不過buffer是周期性的將緩存的元素集合發(fā)送出去,而window周期性的將元素集合以O(shè)bservable的形態(tài)發(fā)送出來。同時buffer要等到元素搜集完畢后,才會發(fā)出元素序列,而window可以實時發(fā)出元素序列
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
let subject = PublishSubject<String>()
//每3個元素作為一個子Observable發(fā)出
subject
.window(timeSpan: 1, count: 3, scheduler:MainScheduler.instance)
.subscribe(onNext: { [weak self] in
print("subscribe: \($0)")
$0.asObservable()
.subscribe(onNext: { print($0) })
.disposed(by: self!.disposeBag)
})
.disposed(by: disposeBag)
subject.onNext("a")
subject.onNext("b")
subject.onNext("c")
subject.onNext("1")
subject.onNext("2")
subject.onNext("3")
}
}
map 該操作符通過傳入一個函數(shù)閉包原來的Observable序列轉(zhuǎn)變?yōu)橐粋€新的Observable序列
let disposeBag = DisposeBag()
Observable.of(1, 2, 3)
.map { $0 * 10 }
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
filter 該操作符就是用來過濾掉某些不符合要求的事件
let disposeBag = DisposeBag()
Observable.of(2, 30, 22, 5, 60, 3, 40, 9)
.filter {
$0 > 10
}
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
distinctUntilChanged 該操作符永雨過濾掉重復(fù)的事件
let disposeBag = DisposeBag()
Observable.of(1, 2, 3, 1, 1, 4)
. distinctUntilChanged()
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
single 限制只發(fā)送一次事件,或者滿足條件的第一個事件,如果存在多個事件或者沒有事件都會發(fā)出一個error事件。如果只有一個事件,則不會發(fā)出error事件
elementAt 該方法實現(xiàn)只處理在指定位置的事件
ignoreElements 該操作符可以忽略掉所有的元素,只發(fā)出error或completed事件
take 該方法僅發(fā)送Observable序列中的前n個事件,在滿足數(shù)量之后會自動.completed
takeLast 該方法實現(xiàn)僅發(fā)送Observable序列中的后n個事件
skip 該方法用于跳過Observable序列發(fā)出的前n個事件
amb 當(dāng)傳入多個Observable到amb操作符時,它將取第一個發(fā)出元素或產(chǎn)生事件的 Observable,然后只發(fā)出它的元素。并忽略掉其他的 Observables。
takeWhile 該方法依次判斷 Observable 序列的每一個值是否滿足給定的條件。 當(dāng)?shù)谝粋€不滿足條件的值出現(xiàn)時,它便自動完成。
takeUntil 除了訂閱源Observable外,通過 takeUntil 方法我們還可以監(jiān)視另外一個 Observable, 即 notifier。如果 notifier 發(fā)出值或 complete 通知,那么源 Observable 便自動完成,停止發(fā)送事件。
skipWhile 該方法用于跳過前面所有滿足條件的事件。一旦遇到不滿足條件的事件,之后就不會再跳過了。
skipUntil 同上面的 takeUntil 一樣,skipUntil 除了訂閱源 Observable 外,通過 skipUntil方法我們還可以監(jiān)視另外一個 Observable, 即 notifier。與 takeUntil 相反的是。源 Observable 序列事件默認(rèn)會一直跳過,直到 notifier 發(fā)出值或 complete 通知。
結(jié)合操作
結(jié)合操作(或者稱合并操作)指的是將多個 Observable 序列進(jìn)行組合,拼裝成一個新的 Observable 序列。
startWith 該方法會在 Observable 序列開始之前插入一些事件元素。即發(fā)出事件消息之前,會先發(fā)出這些預(yù)先插入的事件消息。
merge 該方法可以將多個(兩個或兩個以上的)Observable 序列合并成一個 Observable序列。
zip 該方法可以將多個(兩個或兩個以上的)Observable 序列壓縮成一個 Observable 序列。而且它會等到每個 Observable 事件一一對應(yīng)地湊齊之后再合并。
combineLatest 該方法同樣是將多個(兩個或兩個以上的)Observable 序列元素進(jìn)行合并。但與 zip 不同的是,每當(dāng)任意一個 Observable 有新的事件發(fā)出時,它會將每個 Observable 序列的最新的一個事件元素進(jìn)行合并。
withLatestFrom 該方法將兩個 Observable 序列合并為一個。每當(dāng) self 隊列發(fā)射一個元素時,便從第二個序列中取出最新的一個值。
switchLatest switchLatest 有點像其他語言的switch 方法,可以對事件流進(jìn)行轉(zhuǎn)換。比如本來監(jiān)聽的 subject1,我可以通過更改 variable 里面的 value 更換事件源。變成監(jiān)聽 subject2。
算數(shù),以及聚合操作
toArray 該操作符先把一個序列轉(zhuǎn)成一個數(shù)組,并作為一個單一的事件發(fā)送,然后結(jié)束。
reduce 接受一個初始值,和一個操作符號。將給定的初始值,與序列里的每個值進(jìn)行累計運算。得到一個最終結(jié)果,并將其作為單個值發(fā)送出去。
concat 會把多個 Observable 序列合并(串聯(lián))為一個 Observable 序列。并且只有當(dāng)前面一個 Observable 序列發(fā)出了 completed 事件,才會開始發(fā)送下一個 Observable 序列事件。
連接操作
可連接的序列
1.可連接的序列和一般序列不同在于:有訂閱時不會立刻開始發(fā)送事件消息,只有當(dāng)調(diào)用connect()之后才會開始發(fā)送值
2.可連接的序列可以讓所有的訂閱者訂閱后,才開始發(fā)出事件消息,從而保證我們想要的所有訂閱者都能接收到事件消息
publish 方法會將一個正常的序列轉(zhuǎn)換成一個可連接的序列。同時該序列不會立刻發(fā)送事件,只有在調(diào)用 connect 之后才會開始。
replay 與 publish 不同在于:新的訂閱者還能接收到訂閱之前的事件消息(數(shù)量由設(shè)置的 bufferSize 決定)
multicast 方法還可以傳入一個 Subject,每當(dāng)序列發(fā)送事件時都會觸發(fā)這個 Subject 的發(fā)送。
delay 該操作符會將 Observable 的所有元素都先拖延一段設(shè)定好的時間,然后才將它們發(fā)送出來。
delaySubscription 使用該操作符可以進(jìn)行延時訂閱。即經(jīng)過所設(shè)定的時間后,才對 Observable 進(jìn)行訂閱操作。
materialize 該操作符可以將序列產(chǎn)生的事件,轉(zhuǎn)換成元素。通常一個有限的 Observable 將產(chǎn)生零個或者多個 onNext 事件,最后產(chǎn)生一個 onCompleted 或者onError事件。而 materialize 操作符會將 Observable 產(chǎn)生的這些事件全部轉(zhuǎn)換成元素,然后發(fā)送出來。
dematerialize 該操作符的作用和 materialize 正好相反,它可以將 materialize 轉(zhuǎn)換后的元素還原。
timeout 使用該操作符可以設(shè)置一個超時時間。如果源 Observable 在規(guī)定時間內(nèi)沒有發(fā)任何出元素,就產(chǎn)生一個超時的 error 事件。
using 使用 using 操作符創(chuàng)建 Observable 時,同時會創(chuàng)建一個可被清除的資源,一旦 Observable終止了,那么這個資源就會被清除掉了。
錯誤處理操作
錯誤處理操作符可以用來幫助我們對 Observable 發(fā)出的 error 事件做出響應(yīng),或者從錯誤中恢復(fù)。
catchErrorJustReturn 當(dāng)遇到 error 事件的時候,就返回指定的值,然后結(jié)束。
catchError 該方法可以捕獲 error,并對其進(jìn)行處理。
retry 使用該方法當(dāng)遇到錯誤的時候,會重新訂閱該序列。比如遇到網(wǎng)絡(luò)請求失敗時,可以進(jìn)行重新連接。retry() 方法可以傳入數(shù)字表示重試次數(shù)。不傳的話只會重試一次。
調(diào)試操作
debug 我們可以將 debug 調(diào)試操作符添加到一個鏈?zhǔn)讲襟E當(dāng)中,這樣系統(tǒng)就能將所有的訂閱者、事件、和處理等詳細(xì)信息打印出來,方便我們開發(fā)調(diào)試。
RxSwift.Resources.total 通過將 RxSwift.Resources.total 打印出來,我們可以查看當(dāng)前 RxSwift 申請的所有資源數(shù)量。這個在檢查內(nèi)存泄露的時候非常有用。
除了Observable,RxSwift 還為我們提供了一些特征序列(Traits):Single、Completable、Maybe、Driver、ControlEvent。
區(qū)別:
1.Observable 是能夠用于任何上下文環(huán)境的通用序列。
2.而 Traits 可以幫助我們更準(zhǔn)確的描述序列。同時它們還為我們提供上下文含義、語法糖,讓我們能夠用更加優(yōu)雅的方式書寫代碼。
Single 是 Observable 的另外一個版本。但它不像 Observable 可以發(fā)出多個元素,它要么只能發(fā)出一個元素,要么產(chǎn)生一個 error 事件。
Single 比較常見的例子就是執(zhí)行 HTTP 請求,然后返回一個應(yīng)答或錯誤。不過我們也可以用 Single 來描述任何只有一個元素的序列。
為方便使用,RxSwift 還為 Single 訂閱提供了一個枚舉(SingleEvent):
.success:里面包含該Single的一個元素值
.error:用于包含錯誤
我們可以通過調(diào)用 Observable 序列的.asSingle()方法,將它轉(zhuǎn)換為 Single。
Completable 是 Observable 的另外一個版本。不像 Observable 可以發(fā)出多個元素,它要么只能產(chǎn)生一個 completed 事件,要么產(chǎn)生一個 error 事件。
為方便使用,RxSwift 為 Completable 訂閱提供了一個枚舉(CompletableEvent):
.completed:用于產(chǎn)生完成事件
.error:用于產(chǎn)生一個錯誤
Maybe 同樣是 Observable 的另外一個版本。它介于 Single 和 Completable 之間,它要么只能發(fā)出一個元素,要么產(chǎn)生一個 completed 事件,要么產(chǎn)生一個 error 事件。
我們可以通過調(diào)用 Observable 序列的 .asMaybe()方法,將它轉(zhuǎn)換為 Maybe。
Driver
1.可以說是最復(fù)雜的 trait,它的目標(biāo)是提供一種簡便的方式在 UI 層編寫響應(yīng)式代碼。
2,如果我們的序列滿足如下特征,就可以使用它:
不會產(chǎn)生 error 事件
一定在主線程監(jiān)聽(MainScheduler)
共享狀態(tài)變化(shareReplayLatestWhileConnected)
ControlProperty
1.是專門用來描述 UI 控件屬性,擁有該類型的屬性都是被觀察者(Observable)
2.ControlProperty 具有以下特征:
不會產(chǎn)生 error 事件
一定在 MainScheduler 訂閱(主線程訂閱)
一定在 MainScheduler 監(jiān)聽(主線程監(jiān)聽)
共享狀態(tài)變化
ControlEvent
1.是專門用于描述 UI 所產(chǎn)生的事件,擁有該類型的屬性都是被觀察者(Observable)。
2.ControlEvent 和 ControlProperty 一樣,都具有以下特征:
不會產(chǎn)生 error 事件
一定在 MainScheduler 訂閱(主線程訂閱)
一定在 MainScheduler 監(jiān)聽(主線程監(jiān)聽)
共享狀態(tài)變化
調(diào)度器
1.調(diào)度器(Schedulers)是 RxSwift 實現(xiàn)多線程的核心模塊,它主要用于控制任務(wù)在哪個線程或隊列運行。
2.RxSwift 內(nèi)置了如下幾種 Scheduler:
CurrentThreadScheduler:表示當(dāng)前線程 Scheduler。(默認(rèn)使用這個)
MainScheduler:表示主線程。如果我們需要執(zhí)行一些和 UI 相關(guān)的任務(wù),就需要切換到該 Scheduler運行。
SerialDispatchQueueScheduler:封裝了 GCD 的串行隊列。如果我們需要執(zhí)行一些串行任務(wù),可以切換到這個 Scheduler 運行。
ConcurrentDispatchQueueScheduler:封裝了 GCD 的并行隊列。如果我們需要執(zhí)行一些并發(fā)任務(wù),可以切換到這個 Scheduler 運行。
OperationQueueScheduler:封裝了 NSOperationQueue。
subscribeOn決定數(shù)據(jù)序列的構(gòu)建函數(shù)在哪個 Scheduler 上運行。
observeOn該方法決定在哪個 Scheduler 上監(jiān)聽這個數(shù)據(jù)序列。