RxSwift Observable&Observer和輔助類型

在我們?nèi)粘i_發(fā)中析命,有一些既可是Observable又可是Observer匙姜。舉個(gè)??:

let observable = textField.rx.text
observable.subscribe(onNext: { text in show(text: text) })

在這行代碼中毛秘,textField當(dāng)前文本就是一個(gè)Observable颅和,當(dāng)用戶在textField中輸入時(shí),就會(huì)show文本內(nèi)容茎辐。
再舉個(gè)??:

let disposeBag = DisposeBag()
let observer = textField.rx.text
let observable = Observable<String>.just("A")
observable.bind(to: observer)
          .disposed(by: disposeBag)

這個(gè)時(shí)候宪郊,屏幕上就會(huì)顯示:

textField.png

這時(shí),textField的當(dāng)前文本就是Observer拖陆。
此外弛槐,框架中還有一些輔助類型,既可是Observable又可是Observer依啰。

1. AsyncSubject

AsyncSubject將在Observable產(chǎn)生完成事件后乎串,發(fā)出最后一個(gè)元素(僅僅只有最后一個(gè)元素)。如果Observable沒有發(fā)出任何元素速警,只有一個(gè)完成事件叹誉,那AsyncSubject也只有一個(gè)完成事件。如果Observableerror中止闷旧,那么AsyncSubject只會(huì)將error發(fā)送出來长豁,不會(huì)發(fā)出其它元素。
舉個(gè)??:

let disposeBag = DisposeBag()
//創(chuàng)建一個(gè)AsyncSubject
let subject = AsyncSubject<String>()
//訂閱subject
subject.subscribe{ print($0) }
        .disposed(by: disposeBag)
subject.onNext("B")
subject.onNext("C")
subject.onNext("D")
subject.onCompleted()

這個(gè)時(shí)候輸出:

next(D)
completed

此時(shí)我們?cè)俑脑煲幌拢?/p>

let subject = AsyncSubject<String>()
subject.subscribe{ print($0) }
        .disposed(by: disposeBag)
subject.onNext("B")
subject.onNext("C")
subject.onNext("D")
//SubjectError 自己定義的enum Error
subject.onError(SubjectError.error)

就會(huì)輸出:

error(error)

2. PublishSubject

PublishSubject是將對(duì)觀察者發(fā)送訂閱后產(chǎn)生的元素忙灼,而在訂閱前發(fā)出的元素將不會(huì)發(fā)送給觀察者匠襟。

  • PublishSubject是最普通的Subject,它不需要初始值就能創(chuàng)建
  • PublishSubject的訂閱者從他們開始訂閱的時(shí)間點(diǎn)起该园,可以收到訂閱后Subject發(fā)出的新Event酸舍,而不會(huì)收到他們?cè)谟嗛喦耙寻l(fā)出的Event
    舉個(gè)??:
let disposeBag = DisposeBag()
let subject = PublishSubject<String>()
//由于當(dāng)前沒有訂閱,所以不輸出
subject.onNext("??")
//第一次訂閱
subject.subscribe(onNext: { (element) in
    print("第一次訂閱:\(element)")
}, onCompleted: {
    print("completed")
}).disposed(by: disposeBag)
//當(dāng)前有一個(gè)訂閱爬范,輸出
subject.onNext("??")

//第二次訂閱
subject.subscribe(onNext: { (element) in
    print("第二次訂閱:\(element)")
}, onCompleted: {
    print("completed")
}).disposed(by: disposeBag)
//當(dāng)前有兩個(gè)訂閱 輸出
subject.onNext("??")

//結(jié)束subject
subject.onCompleted()
//再次發(fā)出.next事件
subject.onNext("??")

顯示如下:

第一次訂閱:??
第一次訂閱:??
第二次訂閱:??
第一次訂閱:completed
第二次訂閱:completed
第三次訂閱:completed

3. ReplaySubject

ReplaySubject將對(duì)觀察者發(fā)送全部的元素父腕,無論觀察者是何時(shí)進(jìn)行訂閱的。這里存在多個(gè)版本的ReplaySubject青瀑,有的只會(huì)將最新的n個(gè)元素發(fā)送給觀察者,有的只會(huì)將限制時(shí)間段內(nèi)最新的元素發(fā)送給觀察者萧诫。如果把ReplaySubject當(dāng)作觀察者來使用斥难,注意不要在多個(gè)線程調(diào)用onNext,onErroronCompleted。這樣會(huì)導(dǎo)致無序調(diào)用帘饶,將造成意想不到的結(jié)果哑诊。

  • ReplaySubject在創(chuàng)建時(shí)候需要設(shè)置一個(gè)bufferSize,表示它對(duì)于它發(fā)送過的event的緩存?zhèn)€數(shù)
  • 比如一個(gè)ReplaySubjectbufferSize設(shè)置為 2及刻,它發(fā)出了 3 個(gè).nextevent镀裤,那么它會(huì)將后兩個(gè)(最近的兩個(gè))event給緩存起來竞阐。此時(shí)如果有一個(gè)subscriber訂閱了這個(gè) ReplaySubject,那么這個(gè)subscriber就會(huì)立即收到前面緩存的兩個(gè).nextevent
  • 如果一個(gè)subscriber訂閱已經(jīng)結(jié)束的ReplaySubject暑劝,除了會(huì)收到緩存的.nextevent外骆莹,還會(huì)收到那個(gè)終結(jié)的.error或者.completeevent
    舉個(gè)??:
let disposeBag = DisposeBag()
//創(chuàng)建
let subject = ReplaySubject<String>.create(bufferSize: 0)
//第1次訂閱subject
subject.subscribe{ print("第一次訂閱:\($0)") }
    .disposed(by: disposeBag)
//發(fā)送.next事件
subject.onNext("A")
subject.onNext("B")
//第二次訂閱
subject.subscribe{ print("第二次訂閱:\($0)" )}
    .disposed(by: disposeBag)
//發(fā)送.next事件
subject.onNext("C")
subject.onNext("D")

輸出結(jié)果:

第一次訂閱:next(A)
第一次訂閱:next(B)
第一次訂閱:next(C)
第二次訂閱:next(C)
第一次訂閱:next(D)
第二次訂閱:next(D)

當(dāng)bufferSize改成1時(shí),結(jié)果就變成了:

第一次訂閱:next(A)
第一次訂閱:next(B)
第二次訂閱:next(B)
第一次訂閱:next(C)
第二次訂閱:next(C)
第一次訂閱:next(D)
第二次訂閱:next(D)

如果是2的話担猛,結(jié)果就變成了:

第一次訂閱:next(A)
第一次訂閱:next(B)
第二次訂閱:next(A)
第二次訂閱:next(B)
第一次訂閱:next(C)
第二次訂閱:next(C)
第一次訂閱:next(D)
第二次訂閱:next(D)

4. BehaviorSubject

BehaviorSubject會(huì)把Observable最新元素發(fā)出來(如果不存在最新的元素幕垦,就發(fā)出默認(rèn)元素)。然后將隨后產(chǎn)生的元素發(fā)送出來傅联。如果Observable因?yàn)?code>error事件而中止先改,則不會(huì)發(fā)出任何元素,將error事件發(fā)出來蒸走。

  • BehaviorSubject需要通過一個(gè)默認(rèn)初始值來創(chuàng)建
  • 當(dāng)一個(gè)訂閱者來訂閱它的時(shí)候仇奶,這個(gè)訂閱者會(huì)立即收到 BehaviorSubjects上一個(gè)發(fā)出的event。之后就跟正常的情況一樣比驻,它也會(huì)接收到BehaviorSubject之后發(fā)出的新的event
    舉個(gè)??:
let disposeBag = DisposeBag()
//創(chuàng)建一個(gè)BehaviorSubject
let subject = BehaviorSubject.init(value: "??")
//第一次訂閱
subject.subscribe{ print("第一次訂閱:\($0)") }
        .disposed(by: disposeBag)
//發(fā)送.next事件
subject.onNext("??")
//發(fā)送error事件
subject.onError(NSError(domain: "local", code: 0, userInfo: nil))
//第二次訂閱
subject.subscribe{ print("第二次訂閱:\($0)") }
        .disposed(by: disposeBag)

輸出結(jié)果:

第一次訂閱:next(??)
第一次訂閱:next(??)
第一次訂閱:error(Error Domain=local Code=0 "(null)")
第二次訂閱:error(Error Domain=local Code=0 "(null)")

4. Variable

RxSwift中猜嘱,Variable相當(dāng)于Swift中的var

  • Variable其實(shí)就是對(duì)BehaviorSubject的封裝嫁艇,所以它也必須要通過一個(gè)默認(rèn)的初始值進(jìn)行創(chuàng)建朗伶。
  • Variable具有BehaviorSubject的功能,能夠向它的訂閱者發(fā)出上一個(gè)event以及之后新創(chuàng)建的event步咪。
  • 不同的是论皆,Variable還會(huì)把當(dāng)前發(fā)出的值保存為自己的狀態(tài)。同時(shí)它會(huì)在銷毀時(shí)自動(dòng)發(fā)送.completeevent猾漫,不需要也不能手動(dòng)給Variables發(fā)送completed或者error事件來結(jié)束它点晴。
  • 簡(jiǎn)單地說就是Variable有一個(gè)value屬性,我們改變這個(gè)value屬性的值就相當(dāng)于調(diào)用一般SubjectsonNext()方法悯周,而這個(gè)最新的onNext()的值就被保存在value屬性里了粒督,直到我們?cè)俅涡薷乃?/li>
  • Variables本身沒有subscribe()方法,但是所有Subjects都有一個(gè)asObservable()方法禽翼。我們可以使用這個(gè)方法返回這個(gè)VariableObservable類型屠橄,拿到這個(gè)Observable類型我們就能訂閱它了。
    舉個(gè)??:
let disposeBag = DisposeBag()
let variable = Variable.init("A")
variable.value = "B"
//第一次訂閱
variable.asObservable().subscribe{ print("第一次訂閱:\($0)") }
    .disposed(by: disposeBag)
//修改value
variable.value = "C"
//第二次訂閱
variable.asObservable().subscribe{ print("第二次訂閱:\($0)") }
    .disposed(by: disposeBag)
//修改value
variable.value = "D"

結(jié)果如下:

第一次訂閱:next(B)
第一次訂閱:next(C)
第二次訂閱:next(C)
第一次訂閱:next(D)
第二次訂閱:next(D)
第一次訂閱:completed
第二次訂閱:completed
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末闰挡,一起剝皮案震驚了整個(gè)濱河市锐墙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌长酗,老刑警劉巖溪北,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡之拨,警方通過查閱死者的電腦和手機(jī)茉继,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蚀乔,“玉大人烁竭,你說我怎么就攤上這事∫仪剑” “怎么了颖变?”我有些...
    開封第一講書人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)听想。 經(jīng)常有香客問我腥刹,道長(zhǎng),這世上最難降的妖魔是什么汉买? 我笑而不...
    開封第一講書人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任衔峰,我火速辦了婚禮,結(jié)果婚禮上蛙粘,老公的妹妹穿的比我還像新娘垫卤。我一直安慰自己,他們只是感情好出牧,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開白布穴肘。 她就那樣靜靜地躺著,像睡著了一般舔痕。 火紅的嫁衣襯著肌膚如雪评抚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,158評(píng)論 1 308
  • 那天伯复,我揣著相機(jī)與錄音慨代,去河邊找鬼。 笑死啸如,一個(gè)胖子當(dāng)著我的面吹牛侍匙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播叮雳,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼想暗,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了债鸡?” 一聲冷哼從身側(cè)響起江滨,我...
    開封第一講書人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎厌均,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體告唆,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡棺弊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年晶密,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片模她。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡稻艰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出侈净,到底是詐尸還是另有隱情尊勿,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布畜侦,位于F島的核電站元扔,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏旋膳。R本人自食惡果不足惜澎语,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望验懊。 院中可真熱鬧擅羞,春花似錦、人聲如沸义图。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽碱工。三九已至娃承,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間痛垛,已是汗流浹背草慧。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留匙头,地道東北人漫谷。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像蹂析,于是被迫代替她去往敵國(guó)和親舔示。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容