學(xué)習(xí)RxSwift筆記(一)

RxSwift 使用詳解系列

Rx

Rx是ReactiveX的縮寫,簡單來說就是基于異步事件序列的響應(yīng)式編程。
RxSiwft:他只是基于Swift語言的Rx標(biāo)準(zhǔn)實(shí)現(xiàn)接口庫,所以RxSwift里不包含任何Cocoa或者UI方面的類。
RxCocoa:是基于RxSwift針對(duì)于iOS開發(fā)的一個(gè)庫,他通過Extension的方法給原生的比如UI控件添加了Rx的特性,使得我們更容易訂閱和響應(yīng)這些控件。

??

Obsevable

·Observable<T>這個(gè)類就是Rx框架的基礎(chǔ),我們可以稱它為可觀察序列。它的作用就是可以異步的產(chǎn)生一系列的事件,即一個(gè)Observable<T>對(duì)象會(huì)隨著時(shí)間推移不定期的發(fā)出event(element: T)這樣一個(gè)東西。
·而且這些事件還可以攜帶數(shù)據(jù),他的泛型<T>就是用來指定這個(gè)事件攜帶的數(shù)據(jù)的類型。
·有了可觀察序列,我們還需要有一個(gè)Observer(訂閱者)來訂閱它這樣這個(gè)訂閱者才能收到Observable<T>不是發(fā)出的事件

可以看到事件就是一個(gè)枚舉,也就是說一個(gè)Observable是可以發(fā)出3種不同類型的事件(next,error, completed)

Observable的創(chuàng)建方法
1.just()該方法通過傳入一個(gè)默認(rèn)值來初始化

let observable = Observable<Int>.just(5)

2.of()該方法可以接受可變數(shù)量的參數(shù)(必須要是同類型的)

let observable = Observable.of("A", "B","C")

3.from()該方法需要一個(gè)數(shù)組參數(shù)

let observable = Observable.from(["A", "B","C"])

4.empty()該方法創(chuàng)建一個(gè)空內(nèi)容的Observable

let observable = Observable<Int>

5.never()該方法創(chuàng)建一個(gè)永遠(yuǎn)不會(huì)發(fā)出事件(也不會(huì)終止)的Observable序列

let observable = Observable<Int>.never()

6.error()該方法創(chuàng)建一個(gè)不做任何操作,而是直接發(fā)送一個(gè)錯(cuò)誤的Observable序列

enum MyError: Error {
    case A
    case B
}
let observable = Observable<int>.error(MyError.A)

7.range()該方法通過指定起始和結(jié)束數(shù)值,創(chuàng)建一個(gè)以這個(gè)范圍內(nèi)所有值作為初始值的Observable序列

let observable = Observable.range(start: 1, count: 5)
let observable = Observable.of(1, 2, 3, 4, 5)

8.repeatElement()該方法創(chuàng)建一個(gè)可以無限發(fā)出給定元素的Event的Observable序列(永不終止)

let observable = Observable.repeatElement(1)

9.generate()該方法創(chuàng)建一個(gè)只有當(dāng)提供的所有的判斷條件都為真的時(shí)候,才會(huì)給出動(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()該方法接受一個(gè)block形式的參數(shù),任務(wù)是對(duì)每一個(gè)過來的訂閱進(jìn)行處理

//這個(gè)block有一個(gè)回調(diào)參數(shù)observer就是訂閱這個(gè)Observable對(duì)象的訂閱者
//當(dāng)一個(gè)訂閱者訂閱這個(gè)Observable對(duì)象的時(shí)候,就會(huì)講經(jīng)樂者作為參數(shù)傳入這個(gè)block來執(zhí)行一些內(nèi)容
let observable = Observable<String>.create{ observer in
    observer.onNext("Hello")
    observer.onCompleted()
    //因?yàn)橐粋€(gè)訂閱行為會(huì)有一個(gè)Disposable類型的返回值,所以在結(jié)尾一定要return一個(gè)Disposable
    return Disposables.create()
}

observable.subscribe {
    print($0)
}

11.defferred()該方法相當(dāng)于創(chuàng)建一個(gè)Observable工廠,通過傳入一個(gè)block來執(zhí)行延遲Observable序列創(chuàng)建的行為,而這個(gè)block里就是真正的實(shí)例化序列對(duì)象的地方。

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è)定的時(shí)間,就發(fā)出一個(gè)索引數(shù)的元素。而且他會(huì)一直發(fā)送下去。

let observable = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
observable.subscribe { event in
    print(event)
}

13.timer()
(1).這個(gè)方法有兩種用法,一種是創(chuàng)建的Observable序列在經(jīng)過設(shè)定的一段時(shí)間后,產(chǎn)生唯一的一個(gè)元素

// 5秒鐘后發(fā)出唯一的一個(gè)元素0
let observable = Observable<int>.timer(5, scheduler: MainScheduler.instance)
observable.subscribe { event in
    print(event)
}

(2).另一種是創(chuàng)建的Observable序列在經(jīng)過設(shè)定的一段時(shí)間后,每隔一段時(shí)間產(chǎn)生一個(gè)元素

//延時(shí)5秒后,每隔1秒發(fā)出一個(gè)元素
let observable = Observable<Int>.timer(5, period: 1, scheduler:MainScheduler.instance)
observable.subscribe { event in
    print(event)
}

訂閱Observable

用法一:
我們使用subscribe()訂閱了一個(gè)Observable對(duì)象,該方法的block的回調(diào)參數(shù)就是被發(fā)出的event事件
如果想要獲取到這個(gè)事件中的數(shù)據(jù),可以通過event,element得到

let observable = Observable.of(0, 2, 4, 6, 8, 10)
observable.subscribe { event in
    print(event.element)
}

用法二:
RxSwift還提供了另一個(gè)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()該方法可以手動(dòng)取消一個(gè)訂閱行為

let observable = Observable.of(0, 2, 4, 6, 8, 10)
let subscription = observable.subscribe { event in
    print(event)
}
subscription.dispose()

除了dispose()方法之外,我們更經(jīng)常用到的是一個(gè)叫DisposeBag的對(duì)象來管理多個(gè)訂閱行為的銷毀,他會(huì)在自己快要dealloc的時(shí)候,對(duì)它里面的所有訂閱行為都屌用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)聽事件,然后對(duì)這個(gè)事件作出相應(yīng)。

1.在subscribe方法中創(chuàng)建
創(chuàng)建觀察者最直接的方法就是在Observable的subscribe方法后面描述當(dāng)事件發(fā)生時(shí),需要如何做出響應(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更專注于特定的場(chǎng)景。Binder主要有以下兩個(gè)特征:
·不會(huì)處理錯(cuò)誤事件
·確保綁定都是在給定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)
    }
}

自定義可綁定屬性
方式一:通過對(duì)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)
        }
    }
}

方式二:通過對(duì)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)一個(gè)新的訂閱者剛好訂閱它的時(shí)候,能不能收到Subject以前發(fā)出過的舊事件,如果能的話又能收到多少個(gè)。

PublishSubject

  1. PublishSubject不需要初始值就能創(chuàng)建
  2. PublishSubject的訂閱者從他們呢開始訂閱的時(shí)間點(diǎn)起,可以收到訂閱后Subject發(fā)出的新事件,而不會(huì)收到他們呢在訂閱前已發(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.需要一個(gè)默認(rèn)初始值來創(chuàng)建
2.當(dāng)一個(gè)訂閱者來訂閱它的時(shí)候,這個(gè)訂閱者會(huì)立即收到BehaviorSubject上一個(gè)發(fā)出的事件。之后就跟正常的情況一樣,他也會(huì)接收到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í)候需要設(shè)置一個(gè)bufferSize,表示他對(duì)于他發(fā)送過的事件的緩存?zhèn)€數(shù)。
如果一個(gè)subscriber訂閱已經(jīng)結(jié)束的ReplaySubject,除了會(huì)收到緩存的。next的事件外,還會(huì)收到那個(gè)終結(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其實(shí)就是對(duì)BehaviorSubject的封裝,所以他也必須要通過一個(gè)默認(rèn)的初始值進(jìn)行創(chuàng)建
不同的是,Variable還會(huì)把當(dāng)前發(fā)出的值保存為自己的狀態(tài)。同時(shí)他會(huì)在銷毀時(shí)自動(dòng)發(fā)送.complete的事件,不需要也不能手動(dòng)給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"
    }
}

操作符

變換操作指的是對(duì)原始的Observable序列進(jìn)行一些轉(zhuǎn)換。

buffer 方法作用是緩沖組合,第一個(gè)參數(shù)是緩沖時(shí)間,第二個(gè)參數(shù)是緩沖個(gè)數(shù),第三個(gè)參數(shù)是線程

import UIKit
import RxSwift
import RxCocoa

class ViewController: UIViewController {
    let disposeBag = DisposeBag()
    override func viewDidLoad() {
        super.viewDidLoad()
        let subject = PublishSubject<String>()
        //沒緩存3個(gè)元素則組合起來一起發(fā)出
        //如果1秒鐘內(nèi)不夠3個(gè)也會(huì)發(fā)出(有幾個(gè)發(fā)幾個(gè),一個(gè)都沒有發(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十分相識(shí),不過buffer是周期性的將緩存的元素集合發(fā)送出去,而window周期性的將元素集合以O(shè)bservable的形態(tài)發(fā)送出來。同時(shí)buffer要等到元素搜集完畢后,才會(huì)發(fā)出元素序列,而window可以實(shí)時(shí)發(fā)出元素序列

import UIKit
import RxSwift
import RxCocoa

class ViewController: UIViewController {
    let disposeBag = DisposeBag()
    override func viewDidLoad() {
        super.viewDidLoad()
        let subject = PublishSubject<String>()
        //每3個(gè)元素作為一個(gè)子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 該操作符通過傳入一個(gè)函數(shù)閉包原來的Observable序列轉(zhuǎn)變?yōu)橐粋€(gè)新的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ā)送一次事件,或者滿足條件的第一個(gè)事件,如果存在多個(gè)事件或者沒有事件都會(huì)發(fā)出一個(gè)error事件。如果只有一個(gè)事件,則不會(huì)發(fā)出error事件

elementAt 該方法實(shí)現(xiàn)只處理在指定位置的事件

ignoreElements 該操作符可以忽略掉所有的元素,只發(fā)出error或completed事件

take 該方法僅發(fā)送Observable序列中的前n個(gè)事件,在滿足數(shù)量之后會(huì)自動(dòng).completed

takeLast 該方法實(shí)現(xiàn)僅發(fā)送Observable序列中的后n個(gè)事件

skip 該方法用于跳過Observable序列發(fā)出的前n個(gè)事件

amb 當(dāng)傳入多個(gè)Observable到amb操作符時(shí),它將取第一個(gè)發(fā)出元素或產(chǎn)生事件的 Observable,然后只發(fā)出它的元素。并忽略掉其他的 Observables。

takeWhile 該方法依次判斷 Observable 序列的每一個(gè)值是否滿足給定的條件。 當(dāng)?shù)谝粋€(gè)不滿足條件的值出現(xiàn)時(shí),它便自動(dòng)完成。

takeUntil 除了訂閱源Observable外,通過 takeUntil 方法我們還可以監(jiān)視另外一個(gè) Observable, 即 notifier。如果 notifier 發(fā)出值或 complete 通知,那么源 Observable 便自動(dòng)完成,停止發(fā)送事件。

skipWhile 該方法用于跳過前面所有滿足條件的事件。一旦遇到不滿足條件的事件,之后就不會(huì)再跳過了。

skipUntil 同上面的 takeUntil 一樣,skipUntil 除了訂閱源 Observable 外,通過 skipUntil方法我們還可以監(jiān)視另外一個(gè) Observable, 即 notifier。與 takeUntil 相反的是。源 Observable 序列事件默認(rèn)會(huì)一直跳過,直到 notifier 發(fā)出值或 complete 通知。

結(jié)合操作
結(jié)合操作(或者稱合并操作)指的是將多個(gè) Observable 序列進(jìn)行組合,拼裝成一個(gè)新的 Observable 序列。

startWith 該方法會(huì)在 Observable 序列開始之前插入一些事件元素。即發(fā)出事件消息之前,會(huì)先發(fā)出這些預(yù)先插入的事件消息。

merge 該方法可以將多個(gè)(兩個(gè)或兩個(gè)以上的)Observable 序列合并成一個(gè) Observable序列。

zip 該方法可以將多個(gè)(兩個(gè)或兩個(gè)以上的)Observable 序列壓縮成一個(gè) Observable 序列。而且它會(huì)等到每個(gè) Observable 事件一一對(duì)應(yīng)地湊齊之后再合并。

combineLatest 該方法同樣是將多個(gè)(兩個(gè)或兩個(gè)以上的)Observable 序列元素進(jìn)行合并。但與 zip 不同的是,每當(dāng)任意一個(gè) Observable 有新的事件發(fā)出時(shí),它會(huì)將每個(gè) Observable 序列的最新的一個(gè)事件元素進(jìn)行合并。

withLatestFrom 該方法將兩個(gè) Observable 序列合并為一個(gè)。每當(dāng) self 隊(duì)列發(fā)射一個(gè)元素時(shí),便從第二個(gè)序列中取出最新的一個(gè)值。

switchLatest switchLatest 有點(diǎn)像其他語言的switch 方法,可以對(duì)事件流進(jìn)行轉(zhuǎn)換。比如本來監(jiān)聽的 subject1,我可以通過更改 variable 里面的 value 更換事件源。變成監(jiān)聽 subject2。

算數(shù),以及聚合操作
toArray 該操作符先把一個(gè)序列轉(zhuǎn)成一個(gè)數(shù)組,并作為一個(gè)單一的事件發(fā)送,然后結(jié)束。

reduce 接受一個(gè)初始值,和一個(gè)操作符號(hào)。將給定的初始值,與序列里的每個(gè)值進(jìn)行累計(jì)運(yùn)算。得到一個(gè)最終結(jié)果,并將其作為單個(gè)值發(fā)送出去。

concat 會(huì)把多個(gè) Observable 序列合并(串聯(lián))為一個(gè) Observable 序列。并且只有當(dāng)前面一個(gè) Observable 序列發(fā)出了 completed 事件,才會(huì)開始發(fā)送下一個(gè) Observable 序列事件。

連接操作
可連接的序列
1.可連接的序列和一般序列不同在于:有訂閱時(shí)不會(huì)立刻開始發(fā)送事件消息,只有當(dāng)調(diào)用connect()之后才會(huì)開始發(fā)送值
2.可連接的序列可以讓所有的訂閱者訂閱后,才開始發(fā)出事件消息,從而保證我們想要的所有訂閱者都能接收到事件消息

publish 方法會(huì)將一個(gè)正常的序列轉(zhuǎn)換成一個(gè)可連接的序列。同時(shí)該序列不會(huì)立刻發(fā)送事件,只有在調(diào)用 connect 之后才會(huì)開始。

replay 與 publish 不同在于:新的訂閱者還能接收到訂閱之前的事件消息(數(shù)量由設(shè)置的 bufferSize 決定)

multicast 方法還可以傳入一個(gè) Subject,每當(dāng)序列發(fā)送事件時(shí)都會(huì)觸發(fā)這個(gè) Subject 的發(fā)送。

delay 該操作符會(huì)將 Observable 的所有元素都先拖延一段設(shè)定好的時(shí)間,然后才將它們發(fā)送出來。

delaySubscription 使用該操作符可以進(jìn)行延時(shí)訂閱。即經(jīng)過所設(shè)定的時(shí)間后,才對(duì) Observable 進(jìn)行訂閱操作。

materialize 該操作符可以將序列產(chǎn)生的事件,轉(zhuǎn)換成元素。通常一個(gè)有限的 Observable 將產(chǎn)生零個(gè)或者多個(gè) onNext 事件,最后產(chǎn)生一個(gè) onCompleted 或者onError事件。而 materialize 操作符會(huì)將 Observable 產(chǎn)生的這些事件全部轉(zhuǎn)換成元素,然后發(fā)送出來。

dematerialize 該操作符的作用和 materialize 正好相反,它可以將 materialize 轉(zhuǎn)換后的元素還原。

timeout 使用該操作符可以設(shè)置一個(gè)超時(shí)時(shí)間。如果源 Observable 在規(guī)定時(shí)間內(nèi)沒有發(fā)任何出元素,就產(chǎn)生一個(gè)超時(shí)的 error 事件。

using 使用 using 操作符創(chuàng)建 Observable 時(shí),同時(shí)會(huì)創(chuàng)建一個(gè)可被清除的資源,一旦 Observable終止了,那么這個(gè)資源就會(huì)被清除掉了。

錯(cuò)誤處理操作
錯(cuò)誤處理操作符可以用來幫助我們對(duì) Observable 發(fā)出的 error 事件做出響應(yīng),或者從錯(cuò)誤中恢復(fù)。

catchErrorJustReturn 當(dāng)遇到 error 事件的時(shí)候,就返回指定的值,然后結(jié)束。

catchError 該方法可以捕獲 error,并對(duì)其進(jìn)行處理。

retry 使用該方法當(dāng)遇到錯(cuò)誤的時(shí)候,會(huì)重新訂閱該序列。比如遇到網(wǎng)絡(luò)請(qǐng)求失敗時(shí),可以進(jìn)行重新連接。retry() 方法可以傳入數(shù)字表示重試次數(shù)。不傳的話只會(huì)重試一次。

調(diào)試操作
debug 我們可以將 debug 調(diào)試操作符添加到一個(gè)鏈?zhǔn)讲襟E當(dāng)中,這樣系統(tǒng)就能將所有的訂閱者、事件、和處理等詳細(xì)信息打印出來,方便我們開發(fā)調(diào)試。

RxSwift.Resources.total 通過將 RxSwift.Resources.total 打印出來,我們可以查看當(dāng)前 RxSwift 申請(qǐng)的所有資源數(shù)量。這個(gè)在檢查內(nèi)存泄露的時(shí)候非常有用。

除了Observable,RxSwift 還為我們提供了一些特征序列(Traits):Single、Completable、Maybe、Driver、ControlEvent。

區(qū)別:
1.Observable 是能夠用于任何上下文環(huán)境的通用序列。
2.而 Traits 可以幫助我們更準(zhǔn)確的描述序列。同時(shí)它們還為我們提供上下文含義、語法糖,讓我們能夠用更加優(yōu)雅的方式書寫代碼。

Single 是 Observable 的另外一個(gè)版本。但它不像 Observable 可以發(fā)出多個(gè)元素,它要么只能發(fā)出一個(gè)元素,要么產(chǎn)生一個(gè) error 事件。
Single 比較常見的例子就是執(zhí)行 HTTP 請(qǐng)求,然后返回一個(gè)應(yīng)答或錯(cuò)誤。不過我們也可以用 Single 來描述任何只有一個(gè)元素的序列。

為方便使用,RxSwift 還為 Single 訂閱提供了一個(gè)枚舉(SingleEvent):

.success:里面包含該Single的一個(gè)元素值
.error:用于包含錯(cuò)誤

我們可以通過調(diào)用 Observable 序列的.asSingle()方法,將它轉(zhuǎn)換為 Single。

Completable 是 Observable 的另外一個(gè)版本。不像 Observable 可以發(fā)出多個(gè)元素,它要么只能產(chǎn)生一個(gè) completed 事件,要么產(chǎn)生一個(gè) error 事件。
為方便使用,RxSwift 為 Completable 訂閱提供了一個(gè)枚舉(CompletableEvent):

.completed:用于產(chǎn)生完成事件
.error:用于產(chǎn)生一個(gè)錯(cuò)誤

Maybe 同樣是 Observable 的另外一個(gè)版本。它介于 Single 和 Completable 之間,它要么只能發(fā)出一個(gè)元素,要么產(chǎn)生一個(gè) completed 事件,要么產(chǎn)生一個(gè) error 事件。
我們可以通過調(diào)用 Observable 序列的 .asMaybe()方法,將它轉(zhuǎn)換為 Maybe。

Driver
1.可以說是最復(fù)雜的 trait,它的目標(biāo)是提供一種簡便的方式在 UI 層編寫響應(yīng)式代碼。
2,如果我們的序列滿足如下特征,就可以使用它:

不會(huì)產(chǎn)生 error 事件
一定在主線程監(jiān)聽(MainScheduler)
共享狀態(tài)變化(shareReplayLatestWhileConnected)

ControlProperty
1.是專門用來描述 UI 控件屬性,擁有該類型的屬性都是被觀察者(Observable)
2.ControlProperty 具有以下特征:

不會(huì)產(chǎn)生 error 事件
一定在 MainScheduler 訂閱(主線程訂閱)
一定在 MainScheduler 監(jiān)聽(主線程監(jiān)聽)
共享狀態(tài)變化

ControlEvent
1.是專門用于描述 UI 所產(chǎn)生的事件,擁有該類型的屬性都是被觀察者(Observable)。
2.ControlEvent 和 ControlProperty 一樣,都具有以下特征:

不會(huì)產(chǎn)生 error 事件
一定在 MainScheduler 訂閱(主線程訂閱)
一定在 MainScheduler 監(jiān)聽(主線程監(jiān)聽)
共享狀態(tài)變化

調(diào)度器
1.調(diào)度器(Schedulers)是 RxSwift 實(shí)現(xiàn)多線程的核心模塊,它主要用于控制任務(wù)在哪個(gè)線程或隊(duì)列運(yùn)行。
2.RxSwift 內(nèi)置了如下幾種 Scheduler:
CurrentThreadScheduler:表示當(dāng)前線程 Scheduler。(默認(rèn)使用這個(gè))
MainScheduler:表示主線程。如果我們需要執(zhí)行一些和 UI 相關(guān)的任務(wù),就需要切換到該 Scheduler運(yùn)行。
SerialDispatchQueueScheduler:封裝了 GCD 的串行隊(duì)列。如果我們需要執(zhí)行一些串行任務(wù),可以切換到這個(gè) Scheduler 運(yùn)行。
ConcurrentDispatchQueueScheduler:封裝了 GCD 的并行隊(duì)列。如果我們需要執(zhí)行一些并發(fā)任務(wù),可以切換到這個(gè) Scheduler 運(yùn)行。
OperationQueueScheduler:封裝了 NSOperationQueue。

subscribeOn決定數(shù)據(jù)序列的構(gòu)建函數(shù)在哪個(gè) Scheduler 上運(yùn)行。
observeOn該方法決定在哪個(gè) Scheduler 上監(jiān)聽這個(gè)數(shù)據(jù)序列。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容