概念性的東西就不在這里做過多的陳述了,在這里只說明兩點(diǎn):
RxSwift究竟是什么
RxSwift is a library for composing asynchronous and event-based code by using observable sequences and functional style operators, allowing for parameterized execution via schedulers.
RxSwift幫我們解決了什么問題
- State, and specifically, shared mutable state
- Imperative programming
- Side effects
- Declarative code
- Reactive systems
這里只是很簡(jiǎn)單的介紹了下RxSwift,別問為什么是英文,本人英語水平實(shí)在是不敢在這里班門弄斧,同時(shí)也避免翻譯的不準(zhǔn)確給你造成誤導(dǎo)。你可以在RxSwift的GitHub上找到更多關(guān)于它的詳細(xì)介紹
要使用RxSwift首先需要了解三樣?xùn)|西
Observables(被觀察者)
Observable<T>這個(gè)類提供了Rx的基礎(chǔ)代碼,它能夠產(chǎn)生一個(gè)異步的事件流去傳輸關(guān)于泛型T類型的相關(guān)數(shù)據(jù)。簡(jiǎn)單點(diǎn)說就是它能夠在當(dāng)前類訂閱(接收到)另外一個(gè)類發(fā)送數(shù)據(jù)
Observable<T>這個(gè)類也允許多個(gè)observers響應(yīng)事件去更新UI或者去處理接收到的數(shù)據(jù)
ObservableType這是Observable<T>遵守的一個(gè)協(xié)議,也就限制了一個(gè)Observable只能發(fā)出(或者一個(gè)observers只能接收)三種類型的事件
- A next event: 這個(gè)事件攜帶最新的數(shù)據(jù),observers通過訂閱這個(gè)事件接收到最新的數(shù)據(jù)
- A completed event: 這個(gè)事件表示一個(gè)事件序列的完結(jié),observers接收到這個(gè)事件后就再也接收不到其它任何事件
- An error event: 一個(gè)事件序列因一個(gè)錯(cuò)誤而終止,observers接收到這個(gè)事件后就再也接收不到其它任何事件
Operators
類似于數(shù)學(xué)中的+ - * /,Rx也提供了一些方便我們對(duì)數(shù)據(jù)進(jìn)行處理的操作符
UIDevice.rx.orientation
.filter { value in
return value != .landscape
}.map { _ in
return "Portrait is the best!"
}.subscribe(onNext: { string in
showAlert(text: string)
})
上面的例子中,每當(dāng)設(shè)備的方向發(fā)生改變,我們接收到事件,但是接收到的值并不是我們想要的最終結(jié)果,那我們就需要借助Rx中的操作符對(duì)數(shù)據(jù)進(jìn)行處理

- 首先,filter只會(huì)允許.landscape通過值。如果設(shè)備在橫向模式,訂閱代碼不會(huì)執(zhí)行,因?yàn)閒ilter會(huì)抑制這些事件
- 在value = .portrait的情況下map接收到輸入,并把值轉(zhuǎn)換為一個(gè)字符串輸出的文本"Portrait is the best!"
- 最后你訂閱next事件,在value = .portrait的情況下將接收到已經(jīng)處理完成的文本"Portrait is the best!",你可以調(diào)用一個(gè)方法將這個(gè)文本直接顯示在屏幕上
Schedulers
Schedulers在Rx中等價(jià)于iOS當(dāng)中的dispatch queues,在Rx中已經(jīng)幫我們定義好了許多常用Schedulers,這些定義好的Schedulers可以幫助我們解決開發(fā)中的大部分問題
- ConcurrentDispatchQueueScheduler可以并發(fā)執(zhí)行你的代碼
- OperationQueueScheduler可以讓你在你給定的隊(duì)列上運(yùn)行你的事件序列
在學(xué)習(xí)Rx基礎(chǔ)階段并不會(huì)使用到它,這里只是簡(jiǎn)單的介紹,如果這系列文章能持續(xù)更新的話我打算后面再結(jié)合具體事例進(jìn)行更加詳細(xì)的講解
Getting started
了解完過后就可以學(xué)習(xí)一些Rx的基礎(chǔ)代碼了,首先創(chuàng)建一個(gè)工程,并使用CocoaPods將RxSwift集成到你的項(xiàng)目中,創(chuàng)建一個(gè)playground在你的項(xiàng)目中,以便更流暢的書寫Rx測(cè)試代碼,避免過多的command+R浪費(fèi)很多時(shí)間,完成后應(yīng)該是這樣的

然后定義這樣一個(gè)方法,以便我們進(jìn)行更好的練習(xí)
public func example(of description: String, action: () -> Void) {
print("\n--- Example of:", description, "---")
action()
}
create
首先我們需要知道What is an observable?
常見的兩種方式來創(chuàng)建一個(gè)Observable對(duì)象,一種是通過引入RxCocoa(RxCocoa是對(duì)cocoa進(jìn)行的Rx擴(kuò)展),它已經(jīng)包含了我們常用到的Observable流,比如button的tap事件
let observable = loginButton.rx.tap.asObservable()
也可以使用提供的create函數(shù)來創(chuàng)建一個(gè)Observable對(duì)象
example(of: "create") {
enum MyError: Error {
case anError
}
Observable<String>.create({ (observer) -> Disposable in
observer.onNext("1")
observer.onNext("?")
observer.onCompleted()
// observer.onError(MyError.anError)
return Disposables.create()
}).subscribe({ (event) in
print(event)
}).disposed(by: DisposeBag())
}
//--- Example of: create ---
//next(1)
//next(?)
//completed
Disposing
到這里我們必須要知道dispose,在一個(gè)observable被訂閱前它不做任何事情,subscribe觸發(fā)observable發(fā)送事件直到observable發(fā)送.completed或.error事件終止,如果我們的subscribe沒有收到.completed或.error事件那誰來終止這次observable sequence呢?那就是DisposeBag。Rx官方建議我們每一個(gè)subscribe都應(yīng)該dispose,以免造成內(nèi)存泄漏
example(of: "DisposeBag") {
let disposeBag = DisposeBag()
Observable.of("A", "B", "C").subscribe({
print($0)
}).addDisposableTo(disposeBag)
}

上述事例當(dāng)disposeBag生命周期結(jié)束時(shí),即使subscribe沒有收到.completed或.error事件,observable sequence也將會(huì)被終止
just
example(of: "What is an observable?") {
let one = 1
let observable: Observable<Int> = Observable<Int>.just(one)
}

上面的事例中我們通過Observable.just方法創(chuàng)建了只包含一個(gè)元素的observable sequence,我們可以通過訂閱它獲取到它發(fā)送的事件
subscribe
example(of: "What is an observablee?") {
let one = 1
let observable: Observable<Int> = Observable<Int>.just(one)
observable.subscribe({ (event) in
print(event)
})
}
//print:
//--- Example of: What is an observable? ---
//next(1)
//completed

這個(gè)方法可以訂閱到observable發(fā)出的任何事件,在上面的例子中我們看到observable發(fā)出了兩個(gè)事件next(1) 和 completed
還有一個(gè)跟它很像的訂閱方法,也是我們開發(fā)中經(jīng)常用到的訂閱方法

一目了然,對(duì)應(yīng)的事件在對(duì)應(yīng)的閉包當(dāng)中響應(yīng),需要注意的是這里的參數(shù)就不在是事件了,而是事件攜帶的具體的值。并且對(duì)于我們不關(guān)注的事件是可以省略的哦~
observable.subscribe(onNext: { (Int) in
code
}, onError: { (Error) in
code
}, onCompleted: {
code
}, onDisposed: {
code
})
of
example(of: "of") {
let one = 1
let two = 2
let three = 3
let observable = Observable.of(one, two, three)
observable.subscribe({ (event) in
print(event)
})
}
//print:
//--- Example of: of ---
//next(1)
//next(2)
//next(3)
//completed

上面的事例中我們通過Observable.of方法創(chuàng)建了包含三個(gè)元素的observable squence,我們通過訂閱發(fā)現(xiàn)它使用三次next事件依次發(fā)送我們給它的三個(gè)值,然后發(fā)送completed事件告訴我們這個(gè)observable的生命周期結(jié)束,不會(huì)再發(fā)送新的值。如果我們將三個(gè)值包成一個(gè)數(shù)組會(huì)發(fā)生什么呢?
example(of: "of") {
let one = 1
let two = 2
let three = 3
let observable = Observable.of([one, two, three])
observable.subscribe({ (event) in
print(event)
})
}
//print:
//--- Example of: of ---
//next([1, 2, 3])
//completed
他會(huì)將這個(gè)數(shù)組用一個(gè)next事件發(fā)送給我們,那如果我們開發(fā)中需要給他一個(gè)數(shù)組,讓他依次發(fā)送給我們應(yīng)該怎么辦呢?
from
example(of: "from") {
let one = 1
let two = 2
let three = 3
let observable = Observable.from([one, two, three])
observable.subscribe({ (event) in
print(event)
})
}
//print:
//--- Example of: from ---
//next(1)
//next(2)
//next(3)
//completed

改用from就搞定了,創(chuàng)建observable sequence的方法還有很多,直接上代碼吧
empty
example(of: "empty") { //只能收到completed
let observable = Observable<Void>.empty()
observable.subscribe({ (event) in
print(event)
})
}
//print:
//--- Example of: empty ---
//completed

never
example(of: "never") { //不發(fā)送任何事件
let observable = Observable<Any>.never()
observable.subscribe({ (event) in
print(event)
})
}
//print:

range
example(of: "range") {
let observable = Observable<Int>.range(start: 1, count: 10)
observable.subscribe(onNext: { (i) in
print(i)
})
}
//print:
//--- Example of: range ---
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9
// 10

deferred
example(of: "deferred") {
let disposeBag = DisposeBag()
var flip = false
let factory:Observable<Int> = Observable.deferred({ () -> Observable<Int> in
flip = !flip
if flip {
return Observable.of(1,2,3)
} else {
return Observable.of(4,5,6)
}
})
for _ in 0...3 {
factory.subscribe(onNext: {
print($0, terminator: "")
}).addDisposableTo(disposeBag)
print()
}
}
// --- Example of: deferred ---
// 123
// 456
// 123
// 456

Subject
Subject就相當(dāng)于一個(gè)橋梁或者代理,它既可以作為一個(gè)observer也可以作為一個(gè)Observable。
下面來看幾種不同的Subject:
PublishSubject
PublishSubject只會(huì)發(fā)送給訂閱者訂閱之后的事件,之前發(fā)生的事件將不會(huì)發(fā)送。
example(of: "PublishSubject") {
let subject = PublishSubject<String>()
subject.onNext("Is anyone listening?")
let subscriptionOne = subject.subscribe(onNext: { string in
print(string)
})
subject.on(.next("1"))
subject.onNext("2")
let subscriptionTwo = subject
.subscribe { event in
print("2)", event.element ?? event)
}
subject.onNext("3")
subscriptionOne.dispose()
subject.onNext("4")
// 1
subject.onCompleted()
// 2
subject.onNext("5")
// 3
subscriptionTwo.dispose()
let disposeBag = DisposeBag()
// 4
subject.subscribe {
print("3)", $0.element ?? $0)
}.addDisposableTo(disposeBag)
subject.onNext("?")
}
//--- Example of: PublishSubject ---
//1
//2
//3
//2) 3
//2) 4
//2) completed
//3) completed
如果要保證所有事件都能被訂閱到,可以使用Create主動(dòng)創(chuàng)建或使用ReplaySubject。
如果被觀察者因?yàn)殄e(cuò)誤被終止,PublishSubject只會(huì)發(fā)出一個(gè)錯(cuò)誤的通知。
ReplaySubject
不管訂閱者什么時(shí)候訂閱的都可以把所有發(fā)生過的事件發(fā)送給訂閱者。
example(of: "ReplaySubject") {
// 1
let subject = ReplaySubject<String>.create(bufferSize: 2) //bufferSize指定緩沖區(qū)的大小
let disposeBag = DisposeBag()
// 2
subject.onNext("1")
subject.onNext("2")
subject.onNext("3")
// 3
subject
.subscribe {
print(label: "1)", event: $0)
}
.addDisposableTo(disposeBag)
subject
.subscribe {
print(label: "2)", event: $0)
}
.addDisposableTo(disposeBag)
subject.onNext("4")
subject.onError(MyError.anError)
subject.dispose()
subject
.subscribe {
print(label: "3)", event: $0)
}
.addDisposableTo(disposeBag)
}
// --- Example of: ReplaySubject ---
// 1) 2
// 1) 3
// 2) 2
// 2) 3
// 1) 4
// 2) 4
// 1) anError
// 2) anError
// 3) Object `RxSwift.ReplayMany<Swift.String>` was already disposed.
BehaviorSubject
廣播所有事件給訂閱者,對(duì)于新的訂閱者,廣播最近的一個(gè)事件或者默認(rèn)值
// 1
enum MyError: Error {
case anError
}
// 2
func print<T: CustomStringConvertible>(label: String, event: Event<T>) {
print(label, event.element ?? event.error ?? event)
}
// 3
example(of: "BehaviorSubject") {
// 4
let subject = BehaviorSubject(value: "Initial value")
let disposeBag = DisposeBag()
subject.subscribe {
print(label: "1)", event: $0)
}.addDisposableTo(disposeBag)
subject.onNext("X")
// 1
subject.onError(MyError.anError)
// 2
subject.subscribe {
print(label: "2)", event: $0)
}.addDisposableTo(disposeBag)
}
// --- Example of: BehaviorSubject ---
// 1) Initial value
// 1) X
// 1) anError
// 2) anError
PublishSubject, ReplaySubject, and BehaviorSubject當(dāng)他們被回收時(shí),不會(huì)自動(dòng)發(fā)送完成事件
Variable
Variable是BehaviorSubject的封裝,它和BehaviorSubject不同之處在于,不能向Variable發(fā)送.Complete和.Error,它會(huì)在生命周期結(jié)束被釋放的時(shí)候自動(dòng)發(fā)送.Complete
example(of: "Variable") {
// 1
var variable = Variable("Initial value")
let disposeBag = DisposeBag()
// 2
variable.value = "New initial value"
// 3
variable.asObservable()
.subscribe {
print(label: "1)", event: $0)
}
.addDisposableTo(disposeBag)
// 1
variable.value = "1"
// 2
variable.asObservable()
.subscribe {
print(label: "2)", event: $0)
}
.addDisposableTo(disposeBag)
// 3
variable.value = "2"
// These will all generate errors
// variable.value.onError(MyError.anError)
// variable.asObservable().onError(MyError.anError)
// variable.value = MyError.anError
// variable.value.onCompleted()
// variable.asObservable().onCompleted()
}
// --- Example of: Variable ---
//1) New initial value
//1) 1
//2) 1
//1) 2
//2) 2