前言
Observable
英文直譯為:可觀察的,可看見的亥揖。但是在RxSwift
普遍的稱它為“可觀察序列”,它的作用主要用來形成一條數(shù)據(jù)流或者事件流妙同,所有的操作產(chǎn)生的事件都會(huì)通過Observable
進(jìn)行傳輸。
在Observable
里有三種事件(Event
: Event
枚舉類型矢门,有三個(gè)成員盆色,next
,error
祟剔,completed
) Observable
發(fā)送的所有事件都是一個(gè)Event
:
next
事件主要是當(dāng)Observable
里出現(xiàn)新的數(shù)據(jù)時(shí)會(huì)發(fā)出的事件隔躲,同時(shí)該事件會(huì)攜帶新的數(shù)據(jù)對(duì)象。completed
事件是當(dāng)Observable
不再有新的數(shù)據(jù)出現(xiàn),Observable
被標(biāo)記完成,不再產(chǎn)生數(shù)據(jù).error
事件是當(dāng)數(shù)據(jù)流遇到了錯(cuò)誤會(huì)發(fā)出的事件麸祷,該事件也會(huì)導(dǎo)致Observable
結(jié)束至会。
Observable(可觀察序列)
1. Observable的創(chuàng)建
在RxSwift
中羊始,可以有多種創(chuàng)建Observable
對(duì)象的方法,下面我們逐一介紹:
(1). create()方法
public static func create(_ subscribe: @escaping (AnyObserver<E>) -> Disposable) -> Observable<E> {
return AnonymousObservable(subscribe)
}
create()
方法的參數(shù)是一個(gè)函數(shù)(閉包),根據(jù)閉包來創(chuàng)建序列浑吟,在閉包里面可自定義事件笙纤。函數(shù)需要傳入?yún)?shù)AnyObserver
類型,返回的是Disposable
,AnyObserver
其實(shí)就是觀察者组力,Disposable
是一個(gè)協(xié)議接口省容,里面只有一個(gè)dispose
方法,用來釋放一些資源燎字。整個(gè)create()
方法返回的是一個(gè)AnonymousObservable
(匿名Observable
).
例子:
let createOb = Observable<Int>.create{ (observer) -> Disposable in
observer.onNext(1)
observer.onCompleted()
return Disposables.create()
}
let _ = createOb.subscribe(onNext: { (number) in
print("訂閱:",number)
}, onError: { (error) in
print("error:",error)
}, onCompleted: {
print("完成回調(diào)")
}) {
print("釋放回調(diào)")
}
(2). empty()方法
public static func empty() -> Observable<E> {
return EmptyProducer<E>()
}
final private class EmptyProducer<Element>: Producer<Element> {
override func subscribe<O: ObserverType>(_ observer: O) -> Disposable where O.E == Element {
observer.on(.completed)
return Disposables.create()
}
}
empty()
方法返回一個(gè)EmptyProducer
類腥椒,在這個(gè)類的內(nèi)部實(shí)現(xiàn)了subscribe()
訂閱方法,且只有一個(gè).completed
狀態(tài)候衍,所以笼蛛,empty()
方法是一個(gè)空方法,里面沒有onNext
事件處理蛉鹿,只會(huì)處理onComplete
事件滨砍。
例子:
let emtyOb = Observable<Int>.empty()
let _ = emtyOb.subscribe(onNext: { (number) in
print("訂閱:",number)
}, onError: { (error) in
print("error:",error)
}, onCompleted: {
print("完成回調(diào)")
}) {
print("釋放回調(diào)")
}
(3). just()方法
public static func just(_ element: E) -> Observable<E> {
return Just(element: element)
}
just()
方法是單個(gè)信號(hào)序列創(chuàng)建,只能處理單個(gè)事件榨为,簡(jiǎn)單來說惨好,我們使用just()
方法時(shí)不能將一組數(shù)據(jù)一起處理,只能一個(gè)一個(gè)數(shù)據(jù)進(jìn)行處理随闺。just()
根據(jù)傳入的一個(gè)參數(shù)來創(chuàng)建序列日川,它會(huì)向訂閱者發(fā)送兩個(gè)事件,第一個(gè)發(fā)送帶元素?cái)?shù)據(jù)的.next
事件矩乐,第二個(gè)發(fā)送 .completed
事件龄句。
例子:
let array = ["You","Me"]
Observable<[String]>.just(array)
.subscribe { (event) in
print(event)
}.disposed(by: disposeBag)
let _ = Observable<[String]>.just(array).subscribe(onNext: { (number) in
print("訂閱:",number)
}, onError: { (error) in
print("error:",error)
}, onCompleted: {
print("完成回調(diào)")
}) {
print("釋放回調(diào)")
}
(4). of()方法
public static func of(_ elements: E ..., scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance) -> Observable<E> {
return ObservableSequence(elements: elements, scheduler: scheduler)
}
of()
方法可以接受多個(gè)參數(shù)來創(chuàng)建實(shí)例,但這些參數(shù)必須是同類型散罕,也就是說分歇,of()
方法是just()
方法的升級(jí)版,它可以將一序列的事情組合起來一起處理欧漱。
例子:
Observable<String>.of("Henry","Jeannie")
.subscribe { (event) in
print(event)
}.disposed(by: disposeBag)
// 字典
Observable<[String: Any]>.of(["name":"HuGe","age":18])
.subscribe { (event) in
print(event)
}.disposed(by: disposeBag)
// 數(shù)組
Observable<[String]>.of(["Peter","July"])
.subscribe { (event) in
print(event)
}.disposed(by: disposeBag)
(5). from()方法
public static func from(optional: E?) -> Observable<E> {
return ObservableOptional(optional: optional)
}
from()
方法只接收數(shù)組(數(shù)組职抡,集合)作為參數(shù),并抽取出數(shù)組里的元素來作為數(shù)據(jù)流中的元素,也就是說误甚,from()
根據(jù)傳入的數(shù)組元素來創(chuàng)建序列缚甩。它會(huì)依次發(fā)出.next
事件,最后發(fā)出.completed
事件窑邦,結(jié)果和of()
方法一樣擅威。
例子:
Observable<[String]>.from(optional: ["Hu","Ge"])
.subscribe { (event) in
print(event)
}.disposed(by: disposeBag)
(6). deferred()方法
public static func deferred(_ observableFactory: @escaping () throws -> Observable<E>)
-> Observable<E> {
return Deferred(observableFactory: observableFactory)
}
deferred()
方法是延時(shí)創(chuàng)建Observable
對(duì)象,當(dāng)subscribe
的時(shí)候才去創(chuàng)建冈钦,它為每一個(gè)bserver
創(chuàng)建一個(gè)新的Observable
郊丛;
例子:
//用于標(biāo)記是奇數(shù)、還是偶數(shù)
var isOdd = true
//使用deferred()方法延遲Observable序列的初始化,通過傳入的block來實(shí)現(xiàn)Observable序列的初始化并且返回厉熟。
let factory : Observable<Int> = Observable.deferred {
//讓每次執(zhí)行這個(gè)block時(shí)候都會(huì)讓奇导盅、偶數(shù)進(jìn)行交替
isOdd = !isOdd
//根據(jù)isOdd參數(shù),決定創(chuàng)建并返回的是奇數(shù)Observable庆猫、還是偶數(shù)Observable
if isOdd {
return Observable.of(1, 3, 5 ,7)
}else {
return Observable.of(2, 4, 6, 8)
}
}
//第1次訂閱測(cè)試
factory.subscribe { event in
print("\(isOdd)", event)
}
//第2次訂閱測(cè)試
factory.subscribe { event in
print("\(isOdd)", event)
}
(7). range()方法
public static func range(start: E, count: E, scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance) -> Observable<E> {
return RangeProducer<E>(start: start, count: count, scheduler: scheduler)
}
range()
方法通過指定起始和結(jié)束數(shù)值认轨,創(chuàng)建一個(gè)以這個(gè)范圍內(nèi)所有值作為初始值的 Observable
序列绅络。range()
方法其實(shí)和of()
方法很相似月培,其功能和of()
差不多,我們只要輸出start
和count
然后就能生成一組數(shù)據(jù)恩急,讓它們執(zhí)行onNext
杉畜。值得注意的是,range()
方法只生成Observable
類型衷恭。
例子:
Observable.range(start: 2, count: 5)
.subscribe { (event) in
print(event)
}.disposed(by: disposeBag)
(8). generate()方法
public static func generate(initialState: E, condition: @escaping (E) throws -> Bool, scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance, iterate: @escaping (E) throws -> E) -> Observable<E> {
return Generate(initialState: initialState, condition: condition, iterate: iterate, resultSelector: { $0 }, scheduler: scheduler)
}
generate()
方法創(chuàng)建一個(gè)只有當(dāng)提供的所有的判斷條件都為 true
的時(shí)候此叠,才會(huì)給出動(dòng)作的Observable
序列。generate()
方法是一個(gè)迭代器随珠,它一直循環(huán)onNext
事件灭袁,直到condition
不滿足要求退出。generate()
有四個(gè)參數(shù)窗看,第一個(gè)是最開始的循環(huán)變量茸歧,第二個(gè)是條件,第三個(gè)是迭代器显沈,這個(gè)迭代器每次運(yùn)行都會(huì)返回一個(gè)E
類型软瞎,作為下一次是否執(zhí)行onNext
事件源,而是否正的要執(zhí)行則看是否滿足condition
條件拉讯。其實(shí)我們可以理解generate()
就是一個(gè)循環(huán)體涤浇,其內(nèi)部實(shí)現(xiàn)也正是一個(gè)循環(huán),類似于數(shù)組的遍歷魔慷,具體實(shí)現(xiàn)代碼在GenerateSink
的run
方法只锭。
例子:
Observable.generate(initialState: 0,// 初始值
condition: { $0 < 10}, // 條件1
iterate: { $0 + 2 }) // 條件2 +2
.subscribe { (event) in
print(event)
}.disposed(by: disposeBag)
(9). timer()方法
public static func timer(_ dueTime: RxTimeInterval, period: RxTimeInterval? = nil, scheduler: SchedulerType)
-> Observable<E> {
return Timer(
dueTime: dueTime,
period: period,
scheduler: scheduler
)
}
timer()
方法是創(chuàng)建的Observable
序列在經(jīng)過設(shè)定的一段時(shí)間后,產(chǎn)生唯一的一個(gè)元素院尔,或者每隔一段時(shí)間產(chǎn)生一個(gè)元素蜻展。這取決于period
是否有值。
例子:
let observable = Observable<Int>.timer(5, period: 1, scheduler: MainScheduler.instance)
observable.subscribe { event in
print(event)
}
(10). interval()方法
public static func interval(_ period: RxTimeInterval, scheduler: SchedulerType)
-> Observable<E> {
return Timer(
dueTime: period,
period: period,
scheduler: scheduler
)
}
interval()
方法創(chuàng)建的 Observable
序列每隔一段設(shè)定的時(shí)間召边,會(huì)發(fā)出一個(gè)索引數(shù)的元素铺呵。而且它會(huì)一直發(fā)送下去。差別在于timer()
可以設(shè)置間隔時(shí)間和持續(xù)時(shí)間隧熙,而interval()
的間隔時(shí)間和持續(xù)時(shí)間是一樣的片挂。
例子:
//下面方法讓其每 1秒發(fā)送一次,并且是在主線程(MainScheduler)發(fā)送。
let observable = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
observable.subscribe { event in
print(event)
}
(11). repeatElement()方法
public static func repeatElement(_ element: E, scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance) -> Observable<E> {
return RepeatElement(element: element, scheduler: scheduler)
}
repeatElement()
方法創(chuàng)建一個(gè)可以無限發(fā)出給定元素的Event
的Observable
序列音念,它是無限循環(huán)的沪饺,會(huì)一直循環(huán)onNext方法,不會(huì)終止闷愤。
例子:
Observable<Int>.repeatElement(5)
.subscribe { (event) in
print("訂閱:",event)
}
.disposed(by: disposeBag)
(12). error()方法
public static func error(_ error: Swift.Error) -> Observable<E> {
return ErrorProducer(error: error)
}
final private class ErrorProducer<Element>: Producer<Element> {
private let _error: Swift.Error
init(error: Swift.Error) {
self._error = error
}
override func subscribe<O: ObserverType>(_ observer: O) -> Disposable where O.E == Element {
observer.on(.error(self._error))
return Disposables.create()
}
}
error()
方法是返回一個(gè)只能調(diào)用onError
方法的Observable
序列整葡。其中的onNext
和OnCompleted
方法是不會(huì)執(zhí)行的。
例子:
Observable<String>.error(NSError.init(domain: "ObservableError", code: 10010, userInfo: ["reason":"unknow"]))
.subscribe { (event) in
print("訂閱:",event)
}
.disposed(by: disposeBag)
(13). never()方法
public static func never() -> Observable<E> {
return NeverProducer()
}
final private class NeverProducer<Element>: Producer<Element> {
override func subscribe<O: ObserverType>(_ observer: O) -> Disposable where O.E == Element {
return Disposables.create()
}
}
never()
方法創(chuàng)建一個(gè)永遠(yuǎn)不會(huì)發(fā)出 Event
讥脐,也不會(huì)終止的 Observable
序列遭居。就是返回一個(gè)無終止的觀察者事件序列,可以用來表示無限持續(xù)時(shí)間旬渠。
例子:
let neverSequence = Observable<Int>.never()
_ = neverSequence.subscribe { event in
print(event)
}
2. Observable的訂閱
創(chuàng)建完了 Observable
俱萍,還要使用 subscribe()
方法來訂閱它,并接收它發(fā)出的 Event
告丢。
(1). Subscribes event handler
public func subscribe(_ on: @escaping (Event<E>) -> Void)
-> Disposable {
}
這種subscribe()
方法訂閱了一個(gè) Observable
對(duì)象枪蘑,該方法的 block
的回調(diào)參數(shù)就是被發(fā)出的 event
事件.
例子:
let observable = Observable.of(1, 2, 3)
observable.subscribe { event in
print(event)
print(event.element)
}
這里可以看到初始化 Observable
序列時(shí)設(shè)置的默認(rèn)值都按順序通過 .next
事件發(fā)送出來,等到數(shù)據(jù)都發(fā)送完畢岖免,它還會(huì)自動(dòng)發(fā)一個(gè) .completed
事件出來岳颇。
(2). Subscribes element handler
public func subscribe(onNext: ((E) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)
-> Disposable {
}
這種subscribe()
預(yù)訂方法,它可以把 event
進(jìn)行分類:.next
颅湘,.completed
话侧,.error
以處理不同類型的event
,同時(shí)會(huì)把 event
攜帶的數(shù)據(jù)直接解包出來作為參數(shù).
例子:
let observable = Observable.of("A", "B", "C")
observable.subscribe(onNext: { element in
print(element)
}, onError: { error in
print(error)
}, onCompleted: {
print("completed")
}, onDisposed: {
print("disposed")
})
onNext
、onError
栅炒、onCompleted
和 onDisposed
這四個(gè)回調(diào)參數(shù)都是有默認(rèn)值的掂摔,即它們都是可選的。所以也可以只處理 onNext
而不管其他的情況赢赊。
3. Observable的事件生命周期
public func `do`(onNext: ((E) throws -> Void)? = nil, onError: ((Swift.Error) throws -> Void)? = nil, onCompleted: (() throws -> Void)? = nil, onSubscribe: (() -> Void)? = nil, onSubscribed: (() -> Void)? = nil, onDispose: (() -> Void)? = nil)
-> Observable<E> {
return Do(source: self.asObservable(), eventHandler: { e in
switch e {
case .next(let element):
try onNext?(element)
case .error(let e):
try onError?(e)
case .completed:
try onCompleted?()
}
}, onSubscribe: onSubscribe, onSubscribed: onSubscribed, onDispose: onDispose)
}
當(dāng) Observable
的某些事件產(chǎn)生時(shí)乙漓,你可以使用 do()
操作符來注冊(cè)一些回調(diào)操作。這些回調(diào)會(huì)被單獨(dú)調(diào)用释移,它們會(huì)和 Observable
原本的回調(diào)分離叭披。
可以使用 do()
方法來監(jiān)聽事件的生命周期,它會(huì)在每一次事件發(fā)送前被調(diào)用玩讳,同時(shí)它和 subscribe()
一樣涩蜘,可以通過不同的回調(diào)處理不同類型的 event
。
例子:
let observable = Observable.of("A", "B", "C")
observable.do(onNext: { element in
print("Next:", element)
}, onError: { error in
print("Error:", error)
}, onCompleted: {
print("Completed")
}, onDispose: {
print("Disposed")
})
observable.subscribe(onNext: { element in
print(element)
}, onError: { error in
print(error)
}, onCompleted: {
print("completed")
}, onDisposed: {
print("disposed")
})
4. Observable的銷毀
通過上面的這些內(nèi)容熏纯,我們大概已經(jīng)知道了同诫,當(dāng)一個(gè)Observable
序列被正常創(chuàng)建出來后它不會(huì)馬上就開始被激活從而發(fā)出 event
,而是要等到它被訂閱了才會(huì)激活它樟澜。而 Observable
序列激活之后要一直等到它發(fā)出了.error
或者 .completed
的 event
后误窖,它才被終結(jié)叮盘。
(1). 顯式銷毀--dispose() 方法
當(dāng)一個(gè)訂閱結(jié)束了不再需要了,就可以調(diào)用 dispose()
方法把這個(gè)訂閱給銷毀掉霹俺,防止內(nèi)存泄漏柔吼。訂閱行為被 dispose
了,訂閱將被取消丙唧,并且內(nèi)部資源都會(huì)被釋放愈魏,那么之后 Observable
如果再發(fā)出 event
,這個(gè)已經(jīng) dispose
的訂閱就收不到消息了想际。通常情況下培漏,你是不需要手動(dòng)調(diào)用 dispose
方法的。
例子:
let observable = Observable.of("A", "B", "C")
let observableDispose = observable.subscribe { event in
print(event)
}
observableDispose.dispose()
(2). 隱式銷毀--DisposeBag 方法
DisposeBag
創(chuàng)建一個(gè)對(duì)象來管理多個(gè)訂閱行為的銷毀沼琉,可以把一個(gè) DisposeBag
對(duì)象看成一個(gè)回收垃圾袋北苟,把用過的訂閱行為都放進(jìn)去。
而這個(gè) DisposeBag
就會(huì)在自己快要銷毀 的時(shí)候打瘪,對(duì)它里面的所有訂閱行為都調(diào)用 dispose()
方法。
例子:
let disposeBag = DisposeBag()
let observable = Observable.of(1, 2, 3)
observable.subscribe { event in
print(event)
}.disposed(by: disposeBag)
總結(jié)
這篇內(nèi)容簡(jiǎn)單的介紹了Observable
序列的創(chuàng)建傻昙,訂閱闺骚,和銷毀。這里創(chuàng)建的序列都是最基本的序列妆档,在RxSwift
里面Observable
也存在一些特征序列僻爽,Driver
,Single
贾惦,ControlEvent
...這些特征序列可以幫助我們更準(zhǔn)確的描述序列胸梆,讓我們能夠用更加優(yōu)雅的方式書寫代碼,關(guān)于這些特征序列后面我會(huì)再學(xué)習(xí)须板。關(guān)于Observable
的銷毀好像還有一種方法碰镜,后面研究到了會(huì)回來補(bǔ)充。如文中有錯(cuò)誤還請(qǐng)各位指正习瑰!
最后感謝RxSwift中文文檔.