原創 2017-06-13
RxSwift 這個框架RP框架相信你應該不陌生了,在Objective-C中我們使用比較多的是ReactiveCocoa,從網上找到的入門知識比較零散,我現在就將從官方文檔學習的筆記作為一個記錄,也許對剛開始學習的你會有所幫助。如下就是我通過思維導圖繪制的框架大致內容:
從上圖可以看出,整個框架無外乎圍繞著:
- Observable: 可觀察序列
- Observer:觀察者
- Subjects:觀察和觀察序列橋梁
- Disposable:你可以把它看做一個ARC
- Scheduler:任務執行線程
下面我們就圍繞著這幾大模塊介紹,首先介紹一下Observable:
Observable
在ReactiveX中,Observable<Element>代表的是一個可觀察序列,從字面意思可以看出這是在觀察者模式中的被觀察者,它會向觀察對象發送事件序列:
- .Next(Element):新事件
- .Error(error):帶有異常的事件完成序列
- .Complete():正常事件完結序列
Observable大致需要了解一下知識,我們將圍繞到以下內容進行學習:
Observable 創建
- Create:通過編程方式來創建可觀察對象,創建后的Observeble是可以接收到.onNext、.onError、.onComplete
---------- 示例代碼 ----------
let observable = Observable<String>.create { (observer) -> Disposable in
observer.onNext("hello RxSwift")
observer.onCompleted()
return Disposables.create {
print("disposabled")
}
}
observable.subscribe { (event) in
print("Operator: create \(event)")
}.dispose()
---------- 運行結果 ----------
Operator: create next(hello RxSwift)
Operator: create completed
disposabled
- Defer:延時創建Observable對象,當subscribe的時候才去創建,它為每一個Observer創建一個新的Observable,也就是說每個訂閱者訂閱的對象都是內容相同但是完全獨立的序列;deferr采用一個Factory函數型作為參數,Factory函數返回的是Observable類型。這也是其延時創建Observable的主要實現
---------- 示例代碼 ----------
let defObservable = Observable<String>.deferred { () -> Observable<String> in
return Observable.create({ (observer) -> Disposable in
observer.onNext("create")
observer.onCompleted()
return Disposables.create {
print("disposed")
}
})
}
defObservable.subscribe { (event) in
print("one -- \(event)")
}
defObservable.subscribe { (event) in
print("two -- \(event)")
}
---------- 運行結果 ----------
one -- next(create)
one -- completed
disposed
two -- next(create)
two -- completed
disposed
通過上述例子,相信你已經看出來了在前面說到的:defer創建會為每個Observer創建一個新的獨立的Observable,并且他們具有相同內容,但是好像并沒有體現出defer延遲創建,那么請你注意下面這兩個例子的對比
---------- 示例非defer,這里可能會用到后面講的內容 ----------
var value: String?
let observable = Observable<String>.from(optional: value)
value = "hello RxSwift"
observable.subscribe { (event) in
print(event)
}.dispose()
---------- 運行結果 ----------
completed
上述結果并沒有像我們想象中的那樣也會打印出 onNext事件,這個是為什么呢? 因為在我們訂閱的時候,數據未必已經初始化完成,現在我們把這個例子使用defer重新測試一下:
---------- 示例,通過defer改寫上面 ----------
var value: String?
let observable = Observable<String>.deferred { () -> Observable<String> in
return Observable<String>.from(optional: value)
}
value = "hello RxSwift"
observable.subscribe { (event) in
print(event)
}.dispose()
---------- 運行結果 ---------
next(hello RxSwift)
completed
看到了如期打印出來的onNext結果,這可能才會是你想達到的效果,具體defer還是需要看使用場景,只有在場景中慢慢體會。
- Of / From :這兩個方法都是把一個對象或者數據轉換為可觀察序列,這在你使用Swift中的SequenceType時很有用
---------- of 示例 ----------
Observable<String>.of("hello", "RxSwift").subscribe { (event) in
print("operator: of \(event)")
}.dispose()
---------- 運行結果 ----------
operator: of next(hello)
operator: of next(RxSwift)
operator: of completed
---------- from 示例 ----------
Observable<String>.from(["hello", "RxSwift"]).subscribe { (event) in
print("operator: from \(event)")
}.dispose()
----------- 運行結果 ----------
operator: from next(hello)
operator: from next(RxSwift)
operator: from completed
- Just:將一個對象或者一個Sequence轉換為 一個 可觀察序列,請注意這里與From是完全不相同的:From是轉換為一個或者多個可觀察序列(這取決于你是要將一個還是一個序列進行轉換)。也就是說Just只能包含一個觀察序列,請注意與上面例子結果進行對比
---------- Just 示例對比 ----------
Observable<String>.from(["hello", "RxSwift"]).subscribe { (event) in
print("operator: just \(event)")
}
Observable<Array<String>>.just(["hello", "RxSwift"]).subscribe { (event) in
print("operator: just \(event)")
}
--------- 運行結果 ----------
operator: from next(hello)
operator: from next(RxSwift)
operator: from completed
operator: just next(["hello", "RxSwift"])
operator: just completed
- Interval:創建一個可觀察序列,以特定的時間間隔釋放一系列整數(E -> Int/NSInteger)
----------- 示例 ---------
Observable<Int>.interval(1, scheduler: MainScheduler.instance)
.take(3) // 發送3次Next,后面再講到此方法
.subscribe { (event) in
print("operator: interval \(event)")
}
----------- 運行結果 ---------
operator: interval next(0)
operator: interval next(1)
operator: interval next(2)
operator: interval completed
- Range:創建一個可觀察到的,發射特定序列整數的范圍(E -> Int/NSInteger)
---------- 示例 ----------
Observable<Int>.range(start: 1, count: 5).subscribe { (event) in
print("operator: range \(event)")
}.dispose()
---------- 運行結果 ---------
operator: range next(1)
operator: range next(2)
operator: range next(3)
operator: range next(4)
operator: range next(5)
operator: range completed
- Repeat: 創建一個可多次發送特定item的Observable
---------- 示例 ----------
Observable<String>.repeatElement("hello RxSwift")
.take(3)
.subscribe { (event) in
print("operator: repeat \(event)")
}.dispose()
---------- 運行結果 --------
operator: repeat next(hello RxSwift)
operator: repeat next(hello RxSwift)
operator: repeat next(hello RxSwift)
operator: repeat completed
- Start:
- Timer:在指定的時間后,發送一個特定的Item (E -> Int/NSInteger),請注意這里與Interval的區別(Interval是發送一系列特定Item,而Timer只會發送一個)
---------- 示例 ---------
Observable<Int>.timer(1, scheduler: MainScheduler.instance)
.subscribe { (event) in
print("operator: timer \(event)")
}
---------- 運行結果 ---------
operator: timer next(0)
operator: timer completed
- Empty: 只會發送一個Complete事件
---------- 示例 ----------
Observable<Int>.empty().subscribe { (event) in
print("operator: empty \(event)")
}.dispose()
---------- 運行結果 ----------
operator: empty completed
- Never:你將不會收到任何事件,并且它將永遠不會終止
- Generate:其實是實現了一個迭代器的效果,他有三個參數,第一個是初始值,第二個是條件(滿足條件之后就會繼續執行.Next事件,第三個是迭代器,每次都會返回一個E類型,知道不滿足條件為止
---------- 示例 ----------
Observable<Int>.generate(initialState: 0, condition: { (element: Int) -> Bool in
return element < 10
}, iterate: { element -> Int in
return element + 3
}).subscribe { (event) in
print("operator: generate \(event)")
}.dispose()
----------- 運行結果 ----------
operator: generate next(3)
operator: generate next(6)
operator: generate next(9)
operator: generate completed
上述例子表示的是:我有一個初始變量0, 此時滿足條件 < 10 ,那么就會執行迭代器,每次+3,直到不滿足條件為止
Observable 變換
- Buffer:定期的將需要發射的Items手機到一個buffer的包中,分批次的發射這些包,而不是一次發射一個Item:例如你有[1, 2, 3, 4] ,你可以一次發射一個,也可以一次發射兩個Item或者三個...,你需要仔細的觀察下面的輸出結果,如果需要更好的理解還請你敲一遍代碼
---------- 示例1 一次發射1個Item事件 --------
Observable<Int>.of(1, 2, 3, 4)
.buffer(timeSpan: 1, count: 1, scheduler: MainScheduler.instance)
.subscribe { (event) in
print("operator: buffer \(event)")
}.dispose()
---------- 運行結果 ---------
operator: buffer next([1])
operator: buffer next([2])
operator: buffer next([3])
operator: buffer next([4])
operator: buffer next([])
operator: buffer completed
---------- 示例2 一次發射3個Item事件 --------
Observable<Int>.of(1, 2, 3, 4)
.buffer(timeSpan: 1, count: 3, scheduler: MainScheduler.instance)
.subscribe { (event) in
print("operator: buffer \(event)")
}.dispose()
---------- 運行結果 ---------
operator: buffer next([1, 2, 3])
operator: buffer next([4])
operator: buffer completed
還可以有其他多個不同發射Item事件,請仔細體會上述結果
- Window:與Buffer類似,但是每次發射的不是Item,而是Observables序列(請注意與Buffer的結果比較):
------------ 示例 -----------
Observable<Int>.of(1, 2, 3, 4)
.window(timeSpan: 1, count: 3, scheduler: MainScheduler.instance)
.subscribe { (event) in
print("operator: window \(event)")
// 這里event的element 是一個Observable
event.element?.subscribe({ (event) in
print("operator: window - subObservables \(event)")
}).dispose()
}.dispose()
------------ 運行結果 -----------
operator: window next(RxSwift.AddRef<Swift.Int>)
operator: window - subObservables next(1)
operator: window - subObservables next(2)
operator: window - subObservables next(3)
operator: window - subObservables completed
operator: window next(RxSwift.AddRef<Swift.Int>)
operator: window - subObservables next(4)
operator: window - subObservables completed
operator: window completed
- FlatMap:將一個發射數據的Observable變換為多個Observables,然后將它們發射的數據合并后放進一個單獨的Observable。
FlatMap操作符使用一個指定的函數對原始Observable發射的每一項數據執行變換操作,這個函數返回一個本身也發射數據的Observable,然后FlatMap合并這些Observables發射的數據,最后將合并后的結果當做它自己的數據序列發射
這個方法是很有用的,例如,當你有一個這樣的Observable:它發射一個數據序列,這些數據本身包含Observable成員或者可以變換為Observable,因此你可以創建一個新的Observable發射這些次級Observable發射的數據的完整集合
--------- 示例1 ---------
// 我需要在每一個Item后跟一個新的Item叫做RxSwift
Observable<Int>.of(0, 1, 2)
.flatMap { (element: Int) -> Observable<String> in
return Observable<String>.of("\(element)", "RxSwift")
}
.subscribe { (event) in
print("operator: flatMap \(event)")
}.dispose()
--------- 運行結果 -------
operator: flatMap next(0)
operator: flatMap next(RxSwift)
operator: flatMap next(1)
operator: flatMap next(RxSwift)
operator: flatMap next(2)
operator: flatMap next(RxSwift)
operator: flatMap completed
- GroupBy:將一個Observable分拆為一些Observables集合,它們中的每一個發射原始Observable的一個子序列
----------- 示例 --------
// 我需要將奇數偶數分成兩組
Observable<Int>.of(0, 1, 2, 3, 4, 5)
.groupBy(keySelector: { (element) -> String in
return element % 2 == 0 ? "偶數" : "基數"
})
.subscribe { (event) in
switch event {
case .next(let group):
group.asObservable().subscribe({ (event) in
print("key: \(group.key) \(event)")
})
default:
print("")
}
}
.dispose()
--------- 運行結果 ---------
key: 基數 next(1)
key: 偶數 next(2)
key: 基數 next(3)
key: 偶數 next(4)
key: 基數 next(5)
key: 偶數 completed
key: 基數 completed
- Map:通過一個閉包將原來的序列轉換為一個新序列的操作
---------- 示例 ----------
Observable<String>.of("John", "Tony", "Tom")
.map { return "hello " + $0}
.subscribe { (event) in
print("operator: map \(event)")
}.dispose()
---------- 運行結果 ----------
operator: map next(hello John)
operator: map next(hello Tony)
operator: map next(hello Tom)
operator: map completed
- Scan:從字面意思可以看出是掃描,也就是說該方法會給出一個初始值(seed),每次通過一個函數將上一次的結果與序列中的Item進行處理,每處理完成都會發射.Next事件
----------- 示例 ----------
Observable<String>.of("Rx", "Swift")
.scan("hello ") { (acum, element) in
return acum + element
}.subscribe { (event) in
print("operator: scan \(event)")
}.dispose()
---------- 運行結果 ----------
operator: scan next(hello Rx)
operator: scan next(hello RxSwift)
operator: scan completed
- Reduce:與上述Scan類似,都是初始一個Seed,每次通過函數將上一次的結果與序列中的Item進行處理,但是唯一不同的一點是,只會在最后發射一次.Next事件,將其拿來作數學計算很有用,這個我們將會在后面講到 (** 請注意與上述Scan的結果比較**)
---------- 示例 ----------
Observable<String>.of("Rx", "Swift")
.reduce("hello ") { (accum, element) -> String in
return accum + element
}.subscribe { (event) in
print("operator: reduce \(event)")
}.dispose()
---------- 運行結果 ----------
operator: reduce next(hello RxSwift)
operator: reduce completed
Observable 過濾器
- Debounce:在規定的時間內過濾Item,如下圖:如果debounce開啟的時候此時2、3、4 Item正好到來,那么將無法收到它們的任何時間
----------- 示例 ----------
Observable<Int>.of(1, 2, 3, 4)
.debounce(1, scheduler: MainScheduler.instance)
.subscribe { (event) in
print("operator: debounce \(event)")
}.dispose()
----------- 運行結果 ----------
operator: debounce next(4)
operator: debounce completed
- Distinct:過濾掉可觀察到的重復Item(相信你在使用數據庫的時候回經常使用到distinct),在Swift中使用的是distinctUntilChanged,表示如果發射的事件與上一次不相同那么才會發射此次事件
---------- 示例 ----------
Observable<Int>.of(1, 2, 2, 2, 3)
.distinctUntilChanged()
.subscribe { (event) in
print("operator: distict \(event)")
}.dispose()
---------- 運行結果 ----------
operator: distict next(1)
operator: distict next(2)
operator: distict next(3)
operator: distict completed
- ElementAt:發射第 N 個Item
----------- 示例 ----------
Observable<Int>.of(1, 2, 2, 3, 4)
.elementAt(5)
.subscribe { (event) in
print("operator: elementAt \(event)")
}.dispose()
----------- 運行結果 -----------
operator: elementAt next(3)
operator: elementAt completed
- Filter:僅發射謂詞測試通過的Items
----------- 示例 -----------
Observable<Int>.of(9, 10, 11, 12)
.filter { (element) -> Bool in
element > 10
}.subscribe { (event) in
print("operator: filter \(event)")
}.dispose()
----------- 運行結果 -----------
operator: filter next(11)
operator: filter next(12)
operator: filter completed
- Skip:發射第N(包含N)之后的Items
----------- 示例 -----------
Observable<Int>.of(9, 10, 11, 12)
.skip(2)
.subscribe { (event) in
print("operator: skip \(event)")
}.dispose()
----------- 運行結果 ---------
operator: skip next(11)
operator: skip next(12)
operator: skip completed
- Take: 發射第N(不包含N)之前的Items,與Skip相反效果
----------- 示例 -----------
Observable<Int>.of(9, 10, 11, 12)
.take(2)
.subscribe { (event) in
print("operator: take \(event)")
}.dispose()
---------- 運行結果 -----------
operator: take next(9)
operator: take next(10)
operator: take completed
- TakeLast: 發射第N(包含N)之后的Items,與Skip相同效果
----------- 示例 -----------
Observable<Int>.of(9, 10, 11, 12)
.takeLast(2)
.subscribe { (event) in
print("operator: takeLast \(event)")
}.dispose()
---------- 運行結果 -----------
operator: takeLast next(11)
operator: takeLast next(12)
operator: takeLast completed
結合多個Observables
- Merge:將多個序列的Items合并為一個序列的Items
----------- 示例 ----------
let observable1 = Observable<Int>.of(1, 3, 5)
let observable2 = Observable<Int>.of(2, 4)
Observable.merge(observable1, observable2)
.subscribe { (event) in
print("operator: merge \(event)")
}.dispose()
----------- 運行結果 ----------
operator: merge next(1)
operator: merge next(2)
operator: merge next(3)
operator: merge next(4)
operator: merge next(5)
operator: merge completed
- StartWith:在發射序列Items前新增一個Item
----------- 示例 ----------
Observable<String>.of(" ", "RxSwift", "!")
.startWith("hello")
.reduce("") { (accum, element) -> String in
return accum + element
}.subscribe { (event) in
print("operator: startWith \(event)")
}.dispose()
----------- 運行結果 ----------
operator: startWith next(hello RxSwift!)
operator: startWith completed
- Switch:當你的序列是一個事件序列的序列 (Observable<Observable<T>>) 的時候(也即是二維序列),可以使用 switch 將序列的序列轉換成一維,并且在出現新的序列的時候,自動切換到最新的那個序列上。也就是說會將前一個序列未發射的Item自動取消掉
----------- 示例 ----------
let var1 = Variable(0)
let var2 = Variable(100)
// 序列的序列
let variable = Variable(var1.asObservable())
variable.asObservable()
.switchLatest()
.subscribe { (event) in
print("operator: switchLatest \(event)")
}
var1.value = 1
variable.value = var2.asObservable()
var2.value = 200
----------- 運行結果 ----------
operator: switchLatest next(0)
operator: switchLatest next(1)
operator: switchLatest next(100)
operator: switchLatest next(200)
operator: switchLatest completed
- Zip:將多個序列的Items進行一一合并,但是需要注意的是,它會等到Item對其后合并,未對齊的會舍棄
---------- 示例 -----------
let observable1 = Observable<Int>.of(1, 2, 3, 4, 5)
let observable2 = Observable<String>.of("A", "B", "C", "D")
Observable<String>.zip(observable1, observable2) { (e1: Int, e2: String) -> String in
"\(e1)\(e2)"
}.subscribe { (event) in
print("operator: zip \(event)")
}.dispose()
---------- 運行結果 ----------
operator: zip next(1A)
operator: zip next(2B)
operator: zip next(3C)
operator: zip next(4D)
operator: zip completed
- CombineLatest:如果存在兩條事件隊列,需要同時監聽,那么每當有新的事件發生的時候,combineLatest 會將每個隊列的最新的一個元素進行合并。類似于zip,但是只有當原始的Observable中的每一個都發射了一條數據時zip才發射數據。CombineLatest則在原始的Observable中任意一個發射了數據時發射一條數據。當原始Observables的任何一個發射了一條數據時,CombineLatest使用一個函數結合它們最近發射的數據,然后發射這個函數的返回值
---------- 示例 ----------
let observable1 = Observable<Int>.of(1, 2, 3, 4, 5)
let observable2 = Observable<String>.of("A", "B", "C", "D")
Observable<String>.combineLatest(observable1, observable2, resultSelector: { (e1: Int, e2: String) -> String in
"\(e1)\(e2)"
}).subscribe { (event) in
print("operator: combine \(event)")
}.dispose()
----------- 運行結果 ----------
operator: combine next(1A)
operator: combine next(2A)
operator: combine next(2B)
operator: combine next(3B)
operator: combine next(3C)
operator: combine next(4C)
operator: combine next(4D)
operator: combine next(5D)
operator: combine completed
錯誤處理
- Catch:在收到序列的異常事件時,通過返回另一個序列來持續發送非error事件
----------- 示例 -----------
Observable<UInt8>.create { (observer) -> Disposable in
observer.onNext(0)
observer.onError(CustomError()) // 這里自定義了一個Error
return Disposables.create()
}.catchError { (error) -> Observable<UInt8> in
print(error)
return Observable<UInt8>.of(1, 2)
}.subscribe { (event) in
print("operator: catchError \(event)")
}.dispose()
----------- 運行結果 ----------
operator: catchError next(0)
RxDemo.(CustomError in _53A9E5DF100B211646D927F0B28DE79B)
operator: catchError next(1)
operator: catchError next(2)
operator: catchError completed
- Retry:出現錯誤事件后,重新發送所有事件信息
---------- 示例 -----------
Observable<UInt8>.create { (observer) -> Disposable in
observer.onNext(0)
observer.onError(CustomError())
return Disposables.create()
}.retry(3) // 重復三次
.subscribe { (event) in
print("operator: retry \(event)")
}.dispose()
----------- 運行結果 -----------
operator: retry next(0)
operator: retry next(0)
operator: retry next(0)
operator: retry error(RxDemo.(CustomError in _53A9E5DF100B211646D927F0B28DE79B))
Observable實用操作
- Delay:延遲發射事件
------------ 示例 ------------
print("start time: \(Date())")
Observable<Int>.of(1, 2, 1)
.delay(1, scheduler: MainScheduler.instance)
.subscribe { (event) in
if event.isCompleted {
print("end time: \(Date())")
}
print("operator: delay \(event)")
}
------------ 運行結果 -----------
start time: 2017-06-12 06:10:32 +0000
operator: delay next(1)
operator: delay next(2)
operator: delay next(1)
end time: 2017-06-12 06:10:33 +0000
operator: delay completed
- Do: 在一個序列的每個事件執行之前添加一個執行動作
---------- 示例 ----------
Observable<Int>.of(1, 2, 1)
.do(onNext: { (_) in
print("operator: do previous next")
}, onError: { (_) in
print("operator: do previous error")
}, onCompleted: {
print("operator: do previous complete")
}, onSubscribe: nil, onSubscribed: nil, onDispose: nil)
.subscribe { (event) in
print("operator: delay \(event)")
}.dispose()
---------- 運行結果 ---------
operator: do previous next
operator: delay next(1)
operator: do previous next
operator: delay next(2)
operator: do previous next
operator: delay next(1)
operator: do previous complete
operator: delay completed
- ObserveOn:Observer在指定Scheduler中觀察序列事件
----------- 示例 --------
Observable<Int>.of(1)
.observeOn(ConcurrentDispatchQueueScheduler.init(queue: DispatchQueue(label: "test")))
.subscribe { (event) in
print("operator: observeOn \(Thread.current.isMainThread) \(event)")
}
---------- 運行結果 ----------
operator: observeOn false next(1)
operator: observeOn false completed
- Subscribe:訂閱事件.onNext 、.onError、.onCompleted
----------- 示例 ---------
Observable<String>.of("hello RxSwift").subscribe(onNext: { (element) in
print("operator: onNext \(element)")
}, onError: { (error) in
print("operator: onError \(error)")
}, onCompleted: {
print("operator: onCOmpleted")
}, onDisposed: nil)
----------- 運行結果 ----------
operator: onNext hello RxSwift
operator: onCOmpleted
- SubscribeOn:在指定的Scheduler中操作,參考ObserveOn
----------- 示例 ---------
Observable<Int>.of(1)
.subscribeOn(MainScheduler.instance)
.subscribe { (event) in
print("operator: observeOn \(Thread.current.isMainThread) \(event)")
}
----------- 運行結果 ----------
operator: subscribeOn true next(1)
operator: subscribeOn true completed
- TimeOut:一個序列在指定時間內未發射完成所有事件,那么將會進入.onError
---------- 示例 --------
Observable<Int>.of(1)
.delay(2, scheduler: MainScheduler.instance)
.timeout(1, scheduler: MainScheduler.instance)
.subscribe { (event) in
print("operator: timeout \(event)")
}
---------- 運行結果 ----------
operator: timeout error(Sequence timeout.)
條件運算符和布爾類型運算符
- DefaultIfEmpty:如果是序列中沒有任何Item,那么給定一個default
---------- 示例 -----------
Observable<Int>.empty()
.ifEmpty(default: 0)
.subscribe({ (event) in
print("operator: ifEmpty \(event)")
})
----------- 運行結果 ---------
operator: ifEmpty next(0)
operator: ifEmpty completed
- SkipUntil:丟棄掉第一個序列的所有Items,直到第二個序列的Item出現
--------- 示例 ----------
Observable<String>.of("A", "B", "C")
.skipUntil(Observable<String>.of("D"))
.subscribe { (event) in
print("operator: skipUntil \(event)")
}
--------- 運行結果 --------
operator: skipUntil next(B)
operator: skipUntil next(C)
operator: skipUntil completed
- SkipWhile:丟棄掉所有的Items,直到滿足某個不滿足條件的Item出現
---------- 示例 ---------
Observable<String>.of("AD", "BD", "CD")
.skipWhile({ (element) -> Bool in
element.contains("A")
})
.subscribe { (event) in
print("operator: skipWhile \(event)")
}.dispose()
---------- 運行結果 ---------
operator: skipWhile next(BD)
operator: skipWhile next(CD)
operator: skipWhile completed
- TakeUntil:取得第一個序列所有Items,直到第二個序列發射Item或者終止
---------- 示例 --------
Observable<Int>.of(1, 2, 3, 4, 5, 6, 7, 8, 9)
.takeUntil(Observable<Int>.empty())
.subscribe { (event) in
print("operator: takeUntil \(event)")
}.dispose()
- TakeWhile:取得第一個序列的所有Items,直到出現不滿足條件的Item (請仔細體會與SkipWhile的不同之處)
----------- 示例 ---------
Observable<Int>.of(1, 2, 3, 4, 5, 6, 7, 8, 9)
.takeWhile({ (element) -> Bool in
element < 5
})
.subscribe { (event) in
print("operator: takeUntil \(event)")
}.dispose()
--------- 運行結果 --------
operator: takeWhile next(1)
operator: takeWhile next(2)
operator: takeWhile next(3)
operator: takeWhile next(4)
operator: takeWhile completed
連接操作
- Publish:將一個普通的序列轉換為可連接序列
- RefCount:使一個可連接序列表現為一個普通序列
- Replay:保證所有的Observers所觀察到的事件Items都是相同的,即使它們已經在序列事件已經發射之后才訂閱的 (具體使用將在下一章節的Subjects中講到)
Observer
- Observer作為觀察者,用于來訂閱Observable,它可以用來通知.onNext、.onError、.onCompleted
--------- 示例 --------
Observable<String>.create { (observer) -> Disposable in
observer.on(.next("hello RxSwift"))
observer.onError(CustomError())
return Disposables.create {
print("disposable")
}
}.subscribe { (event) in
print(event)
}.dispose()
--------- 運行結果 ---------
next(hello RxSwift)
error(RxDemo.(CustomError in _53A9E5DF100B211646D927F0B28DE79B))
- AnyObserver使用:
--------- 示例 ----------
let observer1 = AnyObserver<Int> { (event) in
print(event)
}
let observer2 = AnyObserver(observer1)
Observable<Int>.of(1, 2, 3)
.subscribe(observer2)
.dispose()
---------- 運行結果 --------
next(1)
next(2)
next(3)
completed
Subject
Subject在ReactiveX的一些實現中扮演了一種橋梁或者代理的角色,它既可以作為Observer也可以作為Observable來使用。作為觀察者來說它可以訂閱一個或者多個可觀察序列,作為可觀察者來說它可以通過Items的reemitting來觀察,并且還可以發射新的Items事件,我們將從如下四個Subject進行學習:
- AnySubject:僅僅只發送訂閱之后的最后一個Item以及.onCompleted,如果出現錯誤,那么僅僅將只發送.onError
- ReplaySubject:如果一個Observer訂閱了ReplaySubject,那么它將收到訂閱前(在bufferSize大小內)以及訂閱后的所有Items,不管Observer何時訂閱的
---------- 示例 -----------
let replay = ReplaySubject<Int>.create(bufferSize: 3)
replay.onNext(0)
replay.onNext(1)
replay.onNext(2)
replay.onNext(3)
replay.subscribe { (event) in
print("Replay first \(event)")
}
replay.onNext(4)
replay.subscribe { (event) in
print("Replay second \(event)")
}
replay.onNext(5)
replay.onCompleted()
---------- 運行結果 ----------
Replay first next(1)
Replay first next(2)
Replay first next(3)
Replay first next(4)
Replay second next(2)
Replay second next(3)
Replay second next(4)
Replay first next(5)
Replay second next(5)
Replay first completed
Replay second completed
請仔細查看上面的運行結果你可以發現:上述replay被兩次訂閱了之后都會收到訂閱的Items,但是收到訂閱之前的Items是有size限制的,這就與你設置的bufferSize大小有關了。訂閱之后的Items是可以完全收到的
- PublishSubject:與BehaviorSubject有略微不同,從字面意思可以看出Publish是發布,那么就意味著如果一個Observer訂閱了PublishSubject,它就將收到訂閱之后的所有事件,但是不包括訂閱之前的事件(你也可以把他看成一個bufferSize=0的ReplaySubject)
----------- 示例 ---------
let publish = PublishSubject<Int>()
publish.onNext(1)
publish.onNext(2)
publish.subscribe { (event) in
print("Publish \(event)")
}
publish.onNext(3)
publish.onNext(4)
publish.onCompleted()
---------- 運行結果 ---------
// 從結果可以看出,訂閱之前的所有Item是收不到的,請體會與BehaviorSubject之間差異
Publish next(3)
Publish next(4)
Publish completed
-
BehaviorSubject:如果一個Observer訂閱了BehaviorSubject之后,那么它就將收到最近的事件,并且也能夠收到在訂閱之后發射的事件Item (你也可以把它看成一個bufferSize=1 的ReplaySubject)
image
----------- 示例 ----------
let behavior = BehaviorSubject<Int>(value: 0)
behavior.onNext(1)
behavior.onNext(2)
behavior.onNext(3)
let disposable = behavior.subscribe { (event) in
print("Behavior \(event)")
}
behavior.onNext(4)
behavior.onCompleted()
---------- 運行結果 -----------
Behavior next(3) // 收到最近Item事件
Behavior next(4) // 收到訂閱之后所有事件
Behavior completed
- Variable:與BehaviorSubject類似,但是比較特殊的一點就是:在.onError之后它不會終止,只會等待到.onCompleted之后才會被deallocated
注意:至此Subject基本就是這些特殊內容,對于這些特殊內容我建議你敲代碼,看結果來仔細體會它們之間的不同與相同之處
Scheduler
對于Scheduler來說,我們需要了解Concurrent(并行)、Serial(串行)Scheduler就可以了,如下為所有Scheduler腦圖:
- Scheduler:當你在多線程的時候你會用到這個Scheduler
在上面的章節相信你已經熟悉了observeOn/subscribeOn,這里我們就直接上來個例子介紹:
----------- 示例 -----------
Observable<Int>.of(1, 2, 3, 4)
.observeOn(SerialDispatchQueueScheduler(internalSerialQueueName: "test"))
.map { (element) -> Int in
print("scheduler:map --> Main Thread: \(Thread.current.isMainThread)")
return element * 2
}
.subscribeOn(MainScheduler.instance)
.observeOn(MainScheduler.instance)
.subscribe { (event) in
print("scheduler:subscribe --> Main Thread: \(Thread.current.isMainThread)")
print("scheduler \(event)")
}
---------- 運行結果 -----------
scheduler:map --> Main Thread: false
scheduler:map --> Main Thread: false
scheduler:map --> Main Thread: false
scheduler:map --> Main Thread: false
scheduler:subscribe --> Main Thread: true
scheduler next(2)
scheduler:subscribe --> Main Thread: true
scheduler next(4)
scheduler:subscribe --> Main Thread: true
scheduler next(6)
scheduler:subscribe --> Main Thread: true
scheduler next(8)
scheduler:subscribe --> Main Thread: true
scheduler completed
Disposable
什么時候使用Disposable呢?我個人理解就是你訂閱了一個可觀察序列,如果有特殊需求你需要提前取消訂閱時使用。也就是說Disposable是用來取消訂閱的一個工具
- 創建:通過Disposables工具創建
let dis1 = Disposables.create()
let dis2 = Disposables.create {
print("在Dispose之前所做一些工作")
}
let dis3 = Disposables.create([dis1, dis2])
- dispose:通過.dispose()取消或者添加到DisposeBag(你可以將它看成一個非ARC機制下的AutoReleasePool
let disposable = Observable<Int>.of(0, 1, 2)
.subscribe { (event) in
print(event)
}
disposable.dispose()
// 或者
disposable.addDisposableTo(DisposeBag())
至此,RxSwift的入門筆記到此結束,接下來我會繼續介紹RxSwift使用詳解篇相關學習筆記,敬請關注