RxSwift 使用

RxSwift把我們程序中每一個操作都看成一個事件枣接,比如一個TextField中的文本改變耳高,一個按鈕被點擊改鲫,或者一個網(wǎng)絡請求結(jié)束等宵睦,每一個事件源就可以看成一個管道缺脉,也就是sequence瞬沦,比如TextField,當我們改變里面的文本的時候名扛,這個TextField就會不斷的發(fā)出事件院究,從他的這個sequence中不斷的流出跪妥,我們只需要監(jiān)聽這個sequence鞋喇,每流出一個事件就做相應的處理。同理眉撵,Button也是一個sequence侦香,每點擊一次就流出一個事件。也就是我們把每一步都想成是一個事件就好去理解RxSwift了纽疟」藓看下圖是不是很好理解了?

Observable和Observer

理解了觀察者模式這兩個概念就很好理解了污朽,Observable就是可被觀察的散吵,也就是我們說的寶寶,他也是事件源。而Observer就是我們的觀察者矾睦,也就是當收到事件的時候去做某些處理的爸爸媽媽晦款。觀察者需要去訂閱(subscribe)被觀察者,才能收到Observable的事件通知消息顷锰。

創(chuàng)建和訂閱被觀察者

下面創(chuàng)建被觀察者其實就是創(chuàng)建一個Obserable的sequence柬赐,就是創(chuàng)建一個流亡问,然后就可以被訂閱subscribe官紫,這樣被觀察者發(fā)出時間消失,我們就能做相應的處理

DisposeBag

DisposeBag其實就相當于iOS中的ARC似得州藕,會在適當?shù)臅r候銷毀觀察者束世,相當于內(nèi)存管理者吧。

subscribe

subscribe是訂閱sequence發(fā)出的事件床玻,比如next事件毁涉,error事件等。而subscribe(onNext:)是監(jiān)聽sequence發(fā)出的next事件中的element進行處理锈死,他會忽略error和completed事件贫堰。相對應的還有subscribe(onError:) 和 subscribe(onCompleted:)

never

never就是創(chuàng)建一個sequence,但是不發(fā)出任何事件信號待牵。

let disposeBag = DisposeBag()
let neverSequence = Observable<String>.never()

let neverSequenceSubscription = neverSequence
    .subscribe { _ in
        print("This will never be printed")
}.addDisposableTo(disposeBag)`

結(jié)果是什么都不打印

empty

empty就是創(chuàng)建一個空的sequence,只能發(fā)出一個completed事件

let disposeBag = DisposeBag()

    Observable<Int>.empty()
        .subscribe { event in
            print(event)
        }
        .addDisposableTo(disposeBag)

completed

just
just是創(chuàng)建一個sequence只能發(fā)出一種特定的事件其屏,能正常結(jié)束

let disposeBag = DisposeBag()

Observable.just("??")
    .subscribe { event in
        print(event)
    }
    .addDisposableTo(disposeBag)
next(??)
completed
of

of是創(chuàng)建一個sequence能發(fā)出很多種事件信號

let disposeBag = DisposeBag()

Observable.of("??", "??", "??", "??")
    .subscribe(onNext: { element in
        print(element)
    })
    .addDisposableTo(disposeBag)
??
??
??

如果把上面的onNext:去掉的話,結(jié)果會是這樣子缨该,也正好對應了我們subscribe中偎行,subscribe只監(jiān)聽事件。

next(??)
next(??)
next(??)
next(??)
completed

from

from就是從集合中創(chuàng)建sequence贰拿,例如數(shù)組蛤袒,字典或者Set

let disposeBag = DisposeBag()

Observable.from(["??", "??", "??", "??"])
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)

create

我們也可以自定義可觀察的sequence,那就是使用create

create操作符傳入一個觀察者observer膨更,然后調(diào)用observer的onNext妙真,onCompleted和onError方法。返回一個可觀察的obserable序列

let disposeBag = DisposeBag()

let myJust = { (element: String) -> Observable<String> in
    return Observable.create { observer in
        observer.on(.next(element))
        observer.on(.completed)
        return Disposables.create()
    }
}

myJust("??")
    .subscribe { print($0) }
    .addDisposableTo(disposeBag)
next(??)
completed

range

range就是創(chuàng)建一個sequence荚守,他會發(fā)出這個范圍中的從開始到結(jié)束的所有事件

let disposeBag = DisposeBag()

Observable.range(start: 1, count: 10)
    .subscribe { print($0) }
    .addDisposableTo(disposeBag)
next(1)
next(2)
next(3)
next(4)
next(5)
next(6)
next(7)
next(8)
next(9)
next(10)
completed

repeatElement

let disposeBag = DisposeBag()

Observable.repeatElement("??")
    .take(3)
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)
??
??
??

generate

let disposeBag = DisposeBag()

Observable.generate(
        initialState: 0,
        condition: { $0 < 3 },
        iterate: { $0 + 1 }
    )
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)
0
1
2
deferred

deferred會為每一為訂閱者observer創(chuàng)建一個新的可觀察序列

let disposeBag = DisposeBag()
var count = 1

let deferredSequence = Observable<String>.deferred {
    print("Creating \(count)")
    count += 1

    return Observable.create { observer in
        print("Emitting...")
        observer.onNext("??")
        observer.onNext("??")
        observer.onNext("??")
        return Disposables.create()
    }
}

deferredSequence
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)

deferredSequence
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)
Creating 1
Emitting...
??
??
??
Creating 2
Emitting...
??
??
??

error

創(chuàng)建一個可觀察序列隐孽,但不發(fā)出任何正常的事件,只發(fā)出error事件并結(jié)束

let disposeBag = DisposeBag()

Observable<Int>.error(TestError.test)
    .subscribe { print($0) }
    .addDisposableTo(disposeBag)
error(test)

doOn

doOn我感覺就是在直接onNext處理時候健蕊,先執(zhí)行某個方法菱阵,doOnNext( :)方法就是在subscribe(onNext:)前調(diào)用,doOnCompleted(:)就是在subscribe(onCompleted:)前面調(diào)用的缩功。

let disposeBag = DisposeBag()

Observable.of("??", "??", "??", "??")
    .do(onNext: { print("Intercepted:", $0) }, onError: { print("Intercepted error:", $0) }, onCompleted: { print("Completed")  })
    .subscribe(onNext: { print($0) },onCompleted: { print("結(jié)束") })
    .addDisposableTo(disposeBag)
Intercepted: ??
??
Intercepted: ??
??
Intercepted: ??
??
Intercepted: ??
??
Completed
結(jié)束

學會使用Subjects

Subjet是observable和Observer之間的橋梁晴及,一個Subject既是一個Obserable也是一個Observer,他既可以發(fā)出事件嫡锌,也可以監(jiān)聽事件虑稼。

PublishSubject

當你訂閱PublishSubject的時候琳钉,你只能接收到訂閱他之后發(fā)生的事件。subject.onNext()發(fā)出onNext事件蛛倦,對應的還有onError()和onCompleted()事件

let disposeBag = DisposeBag()
let subject = PublishSubject<String>()

subject.addObserver("1").addDisposableTo(disposeBag)
subject.onNext("??")
subject.onNext("??")

subject.addObserver("2").addDisposableTo(disposeBag)
subject.onNext("???")
subject.onNext("???")`
Subscription: 1 Event: next(??)
Subscription: 1 Event: next(??)
Subscription: 1 Event: next(???)
Subscription: 2 Event: next(???)
Subscription: 1 Event: next(???)
Subscription: 2 Event: next(???)`

ReplaySubject

當你訂閱ReplaySubject的時候歌懒,你可以接收到訂閱他之后的事件,但也可以接受訂閱他之前發(fā)出的事件溯壶,接受幾個事件取決與bufferSize的大小

let disposeBag = DisposeBag()
let subject = ReplaySubject<String>.create(bufferSize: 1)

subject.addObserver("1").addDisposableTo(disposeBag)
subject.onNext("??")
subject.onNext("??")

subject.addObserver("2").addDisposableTo(disposeBag)
subject.onNext("???")
subject.onNext("???")
Subscription: 1 Event: next(??)
Subscription: 1 Event: next(??)
Subscription: 2 Event: next(??) //訂閱之后還可以接受一次前面發(fā)出的事件
Subscription: 1 Event: next(???)
Subscription: 2 Event: next(???)
Subscription: 1 Event: next(???)
Subscription: 2 Event: next(???)

BehaviorSubject

當你訂閱了BehaviorSubject及皂,你會接受到訂閱之前的最后一個事件。

let disposeBag = DisposeBag()
let subject = BehaviorSubject(value: "??")

subject.addObserver("1").addDisposableTo(disposeBag)
subject.onNext("??")
subject.onNext("??")

subject.addObserver("2").addDisposableTo(disposeBag)
subject.onNext("???")
subject.onNext("???")

subject.addObserver("3").addDisposableTo(disposeBag)
subject.onNext("??")
subject.onNext("??")
Subscription: 1 Event: next(??)
Subscription: 1 Event: next(??)
Subscription: 1 Event: next(??)
Subscription: 2 Event: next(??)    //訂閱之前的最后一個事件
Subscription: 1 Event: next(???)
Subscription: 2 Event: next(???)
Subscription: 1 Event: next(???)
Subscription: 2 Event: next(???)
Subscription: 3 Event: next(???) //訂閱之前的最后一個事件
Subscription: 1 Event: next(??)
Subscription: 3 Event: next(??)
Subscription: 2 Event: next(??)
Subscription: 1 Event: next(??)
Subscription: 3 Event: next(??)
Subscription: 2 Event: next(??)

PublishSubject, ReplaySubject和BehaviorSubject是不會自動發(fā)出completed事件的且改。

Variable

Variable是BehaviorSubject一個包裝箱验烧,就像是一個箱子一樣,使用的時候需要調(diào)用asObservable()拆箱又跛,里面的value是一個BehaviorSubject碍拆,他不會發(fā)出error事件,但是會自動發(fā)出completed事件

let disposeBag = DisposeBag()
let variable = Variable("??")

variable.asObservable().addObserver("1").addDisposableTo(disposeBag)
variable.value = "??"
variable.value = "??"

variable.asObservable().addObserver("2").addDisposableTo(disposeBag)
variable.value = "???"
variable.value = "???"
Subscription: 1 Event: next(??)
Subscription: 1 Event: next(??)
Subscription: 1 Event: next(??)
Subscription: 2 Event: next(??)
Subscription: 1 Event: next(???)
Subscription: 2 Event: next(???)
Subscription: 1 Event: next(???)
Subscription: 2 Event: next(???)
Subscription: 1 Event: completed
Subscription: 2 Event: completed

聯(lián)合操作

聯(lián)合操作就是把多個Observable流合成單個Observable流

startWith

在發(fā)出事件消息之前慨蓝,先發(fā)出某個特定的事件消息感混。比如發(fā)出事件2 ,3然后我startWith(1)礼烈,那么就會先發(fā)出1弧满,然后2 ,3.

![693607-f2f8af4760c09dd122222.jpeg](http://upload-images.jianshu.io/upload_images/1935872-38d23e1661ff2d65.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
let disposeBag = DisposeBag()

Observable.of("2", "3")
    .startWith("1")
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)
1
2
3
merge

合并兩個Observable流合成單個Observable流济丘,根據(jù)時間軸發(fā)出對應的事件


let disposeBag = DisposeBag()

let subject1 = PublishSubject<String>()
let subject2 = PublishSubject<String>()

Observable.of(subject1, subject2)
    .merge()
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)

subject1.onNext("???")

subject1.onNext("???")

subject2.onNext("①")

subject2.onNext("②")

subject1.onNext("??")

subject2.onNext("③")
???
???
①
②
??
③
zip
let disposeBag = DisposeBag()

let stringSubject = PublishSubject<String>()
let intSubject = PublishSubject<Int>()

Observable.zip(stringSubject, intSubject) { stringElement, intElement in
    "\(stringElement) \(intElement)"
    }
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)

stringSubject.onNext("???")
stringSubject.onNext("???")

intSubject.onNext(1)

intSubject.onNext(2)

stringSubject.onNext("??")
intSubject.onNext(3)
??? 1    將stringSubject和intSubject壓縮到一起共同處理
??? 2
?? 3
combineLatest

綁定超過最多不超過8個的Observable流谱秽,結(jié)合在一起處理。和Zip不同的是combineLatest是一個流的事件對應另一個流的最新的事件摹迷,兩個事件都會是最新的事件疟赊,可將下圖與Zip的圖進行對比。

let disposeBag = DisposeBag()

let stringSubject = PublishSubject<String>()
let intSubject = PublishSubject<Int>()

Observable.combineLatest(stringSubject, intSubject) { stringElement, intElement in
        "\(stringElement) \(intElement)"
    }
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)

stringSubject.onNext("???")

stringSubject.onNext("???")
intSubject.onNext(1)

intSubject.onNext(2)

stringSubject.onNext("??")

??? 1
??? 2
?? 2
switchLatest

switchLatest可以對事件流進行轉(zhuǎn)換峡碉,本來監(jiān)聽的subject1近哟,我可以通過更改variable里面的value更換事件源。變成監(jiān)聽subject2了

let disposeBag = DisposeBag()

let subject1 = BehaviorSubject(value: "??")
let subject2 = BehaviorSubject(value: "??")

let variable = Variable(subject1)

variable.asObservable()
    .switchLatest()
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)

subject1.onNext("??")
subject1.onNext("??")

variable.value = subject2

subject1.onNext("??")

subject2.onNext("??")
variable.value = subject1
subject2.onNext("田騰飛")
subject1.onNext("沸騰天"

??
??
??
??
??
??
沸騰天

變換操作

map

通過傳入一個函數(shù)閉包把原來的sequence轉(zhuǎn)變?yōu)橐粋€新的sequence的操作

et disposeBag = DisposeBag()
Observable.of(1, 2, 3)
    .map { $0 * $0 }
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)
1    每一個元素自己相乘
4
9
flatMap

將一個sequence轉(zhuǎn)換為一個sequences鲫寄,當你接收一個sequence的事件吉执,你還想接收其他sequence發(fā)出的事件的話可以使用flatMap,她會將每一個sequence事件進行處理以后地来,然后再以一個sequence形式發(fā)出事件戳玫。而且flatMap有一次拆包動作,請看代碼解析未斑。

let disposeBag = DisposeBag()

struct Player {
    var score: Variable<Int>        //里面是一個Variable
}

let ???? = Player(score: Variable(80))        
let ???? = Player(score: Variable(90))
let ?? = Player(score: Variable(550))

let player = Variable(????)  //將player轉(zhuǎn)為Variable

player.asObservable()        //拆箱轉(zhuǎn)成可被監(jiān)聽的sequence
    .flatMap { $0.score.asObservable() } // flatMap有一次拆包動作咕宿,$0本來應該是一個BehaviorSubject類型,但是直接訪問了score。所以猜想flatMap對behaviorSubject進行了onNext拆包取數(shù)據(jù)
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)

????.score.value = 85

player.value = ???? //更換了value府阀,相當于又添加了一個sequence缆镣,兩個sequence都可以接收

????.score.value = 95
????.score.value = 222
player.value = ??

????.score.value = 100`
80
85
90
95
222
550
100
flatMapLatest

flatMapLatest只會接收最新的value事件,將上例改為flatMapLatest试浙。結(jié)果為

80
85
90
550
scan

scan就是給一個初始化的數(shù)董瞻,然后不斷的拿前一個結(jié)果和最新的值進行處理操作。

let disposeBag = DisposeBag()

Observable.of(10, 100, 1000)
    .scan(1) { aggregateValue, newValue in
        aggregateValue + newValue
    }
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)
11
111
1111

過濾和約束

filter

filter很好理解田巴,就是過濾掉某些不符合要求的事件


Observable.of(
    "??", "??", "??",
    "??", "??", "??",
    "??", "??", "??")
    .filter {
        $0 == "??"
    }
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)

??
??
??

distinctUntilChanged

distinctUntilChanged就是當下一個事件與前一個事件是不同事件的事件才進行處理操作

let disposeBag = DisposeBag()

Observable.of("??", "??", "??", "??", "??", "??", "??")
    .distinctUntilChanged()
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)
??
??
??
??
??
elementAt

只處理在指定位置的事件

let disposeBag = DisposeBag()

Observable.of("??", "??", "??", "??", "??", "??")
    .elementAt(3)
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)
??
single

找出在sequence只發(fā)出一次的事件钠糊,如果超過一個就會發(fā)出error錯誤

Observable.of("??", "??", "??", "??", "??", "??")
    .single()
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)
??    //單一信號超過了一個
Received unhandled error: /var/folders/hz/v15ld5mj0nqf83d21j13y0tw0000gn/T/./lldb/7229/playground107.swift:69:__lldb_expr_107 -> Sequence contains more than one element.
Observable.of("??", "??", "??", "??", "??", "??")
    .single { $0 == "??" }        //青蛙只有一個,completed
    .subscribe { print($0) }
    .addDisposableTo(disposeBag)

Observable.of("??", "??", "??", "??", "??", "??")
    .single { $0 == "??" } //兔子有兩個固额,會發(fā)出error
    .subscribe { print($0) }
    .addDisposableTo(disposeBag)
Observable.of("??", "??", "??", "??", "??", "??")
    .single { $0 == "??" } //沒有藍色球眠蚂,會發(fā)出error
    .subscribe { print($0) }
    .addDisposableTo(disposeBag)
take

只處理前幾個事件信號,

let disposeBag = DisposeBag()

Observable.of("??", "??", "??", "??", "??", "??")
    .take(3)
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)

??
??
??
takeLast

只處理后幾個事件信號

let disposeBag = DisposeBag()

Observable.of("??", "??", "??", "??", "??", "??")
    .takeLast(3)
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)
??
??
??
takeWhile

當條件滿足的時候進行處理

let disposeBag = DisposeBag()

Observable.of(1, 2, 3, 4, 5, 6)
    .takeWhile { $0 < 4 }
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)

1
2
3
takeUntil

接收事件消息煞聪,直到另一個sequence發(fā)出事件消息的時候斗躏。

let disposeBag = DisposeBag()

let sourceSequence = PublishSubject<String>()
let referenceSequence = PublishSubject<String>()

sourceSequence
    .takeUntil(referenceSequence)
    .subscribe { print($0) }
    .addDisposableTo(disposeBag)

sourceSequence.onNext("??")
sourceSequence.onNext("??")
sourceSequence.onNext("??")

referenceSequence.onNext("??")    //停止接收消息

sourceSequence.onNext("??")
sourceSequence.onNext("??")
sourceSequence.onNext("??")
next(??)
next(??)
next(??)
completed
skip

取消前幾個事件

let disposeBag = DisposeBag()

Observable.of("??", "??", "??", "??", "??", "??")
    .skip(2)
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)
??
??
??
??
skipWhile

滿足條件的事件消息都取消

let disposeBag = DisposeBag()

Observable.of(1, 2, 3, 4, 5, 6)
    .skipWhile { $0 < 4 }
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)

4
5
6
skipWhileWithIndex

滿足條件的都被取消,傳入的閉包同skipWhile有點區(qū)別而已

Observable.of("??", "??", "??", "??", "??", "??")
    .skipWhileWithIndex { element, index in
        index < 3
    }
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)
skipUntil

直到某個sequence發(fā)出了事件消息昔脯,才開始接收當前sequence發(fā)出的事件消息

let disposeBag = DisposeBag()

let sourceSequence = PublishSubject<String>()
let referenceSequence = PublishSubject<String>()

sourceSequence
    .skipUntil(referenceSequence)
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)

sourceSequence.onNext("??")
sourceSequence.onNext("??")
sourceSequence.onNext("??")

referenceSequence.onNext("??")

sourceSequence.onNext("??")
sourceSequence.onNext("??")
sourceSequence.onNext("??")
}

數(shù)學操作

toArray

將sequence轉(zhuǎn)換成一個array啄糙,并轉(zhuǎn)換成單一事件信號,然后結(jié)束

let disposeBag = DisposeBag()

Observable.range(start: 1, count: 10)
    .toArray()
    .subscribe { print($0) }
    .addDisposableTo(disposeBag)
next([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
completed
reduce

用一個初始值云稚,對事件數(shù)據(jù)進行累計操作隧饼。reduce接受一個初始值,和一個操作符號

let disposeBag = DisposeBag()

Observable.of(10, 100, 1000)
    .reduce(1, accumulator: +)
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)

1111

concat

concat會把多個sequence和并為一個sequence静陈,并且當前面一個sequence發(fā)出了completed事件燕雁,才會開始下一個sequence的事件。

在第一sequence完成之前鲸拥,第二個sequence發(fā)出的事件都會被忽略拐格,但會接收一完成之前的二發(fā)出的最后一個事件。不好解釋刑赶,看例子說明

let disposeBag = DisposeBag()

let subject1 = BehaviorSubject(value: "??")
let subject2 = BehaviorSubject(value: "??")

let variable = Variable(subject1)

variable.asObservable()
    .concat()
    .subscribe { print($0) }
    .addDisposableTo(disposeBag)

subject1.onNext("??")
subject1.onNext("??")

variable.value = subject2


subject2.onNext("??")    //1完成前捏浊,會被忽略
subject2.onNext("teng") //1完成前,會被忽略
subject2.onNext("fei")    //1完成前的最后一個撞叨,會被接收

subject1.onCompleted()

subject2.onNext("??")
next(??)
next(??)
next(??)
next(fei)
next(??)

連接性操作

Connectable Observable有訂閱時不開始發(fā)射事件消息金踪,而是僅當調(diào)用它們的connect()方法時。這樣就可以等待所有我們想要的訂閱者都已經(jīng)訂閱了以后牵敷,再開始發(fā)出事件消息胡岔,這樣能保證我們想要的所有訂閱者都能接收到事件消息。其實也就是等大家都就位以后枷餐,開始發(fā)出消息

publish

將一個正常的sequence轉(zhuǎn)換成一個connectable sequence

let intSequence = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
    .publish()

_ = intSequence
    .subscribe(onNext: { print("Subscription 1:, Event: \($0)") })

delay(2) { _ = intSequence.connect() } //相當于把事件消息推遲了兩秒

delay(4) {
    _ = intSequence
        .subscribe(onNext: { print("Subscription 2:, Event: \($0)") })
}

delay(6) {
    _ = intSequence
        .subscribe(onNext: { print("Subscription 3:, Event: \($0)") })
}
Subscription 1:, Event: 0
Subscription 1:, Event: 1
Subscription 2:, Event: 1
Subscription 1:, Event: 2
Subscription 2:, Event: 2
Subscription 1:, Event: 3
Subscription 3:, Event: 3
Subscription 2:, Event: 3
Subscription 1:, Event: 4
Subscription 3:, Event: 4
replay

將一個正常的sequence轉(zhuǎn)換成一個connectable sequence靶瘸,然后和replaySubject相似,能接收到訂閱之前的事件消息。

let intSequence = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
    .replay(5)    //接收到訂閱之前的5條事件消息

_ = intSequence
    .subscribe(onNext: { print("Subscription 1:, Event: \($0)") })

delay(2) { _ = intSequence.connect() }

delay(4) {
    _ = intSequence
        .subscribe(onNext: { print("Subscription 2:, Event: \($0)") })
}

delay(8) {
    _ = intSequence
        .subscribe(onNext: { print("Subscription 3:, Event: \($0)") })
}
multicast

將一個正常的sequence轉(zhuǎn)換成一個connectable sequence奕锌,并且通過特性的subject發(fā)送出去著觉,比如PublishSubject,或者replaySubject惊暴,behaviorSubject等饼丘。不同的Subject會有不同的結(jié)果。

let subject = PublishSubject<Int>()

_ = subject
    .subscribe(onNext: { print("Subject: \($0)") })

let intSequence = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
    .multicast(subject)

_ = intSequence
    .subscribe(onNext: { print("\tSubscription 1:, Event: \($0)") })

delay(2) { _ = intSequence.connect() }

delay(4) {
    _ = intSequence
        .subscribe(onNext: { print("\tSubscription 2:, Event: \($0)") })
}
錯誤處理

catchErrorJustReturn

遇到error事件的時候辽话,就return一個值肄鸽,然后結(jié)束

let disposeBag = DisposeBag()

let sequenceThatFails = PublishSubject<String>()

sequenceThatFails
    .catchErrorJustReturn("??")
    .subscribe { print($0) }
    .addDisposableTo(disposeBag)

sequenceThatFails.onNext("??")
sequenceThatFails.onNext("??")
sequenceThatFails.onNext("??")
sequenceThatFails.onNext("??")
sequenceThatFails.onError(TestError.test)
next(??)
next(??)
next(??)
next(??)
next(??)
completed
catchError

捕獲error進行處理,可以返回另一個sequence進行訂閱

let disposeBag = DisposeBag()

let sequenceThatFails = PublishSubject<String>()
let recoverySequence = PublishSubject<String>()

sequenceThatFails
    .catchError {
        print("Error:", $0)
        return recoverySequence
    }
    .subscribe { print($0) }
    .addDisposableTo(disposeBag)

sequenceThatFails.onNext("??")
sequenceThatFails.onNext("??")
sequenceThatFails.onNext("??")
sequenceThatFails.onNext("??")
sequenceThatFails.onError(TestError.test)

recoverySequence.onNext("??")
next(??)
next(??)
next(??)
next(??)
Error: test
next(??)
retry

遇見error事件可以進行重試油啤,比如網(wǎng)絡請求失敗典徘,可以進行重新連接

let disposeBag = DisposeBag()
var count = 1

let sequenceThatErrors = Observable<String>.create { observer in
    observer.onNext("??")
    observer.onNext("??")
    observer.onNext("??")

    if count == 1 {
        observer.onError(TestError.test)
        print("Error encountered")
        count += 1
    }

    observer.onNext("??")
    observer.onNext("??")
    observer.onNext("??")
    observer.onCompleted()

    return Disposables.create()
}

sequenceThatErrors
    .retry(3)        //不傳入數(shù)字的話,只會重試一次
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)

debug

debug

打印所有的訂閱, 事件和disposals

sequenceThatErrors
    .retry(3)
    .debug()
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)

RxSwift.Resources.total

查看RxSwift所有資源的占用

print(RxSwift.Resources.total)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末益咬,一起剝皮案震驚了整個濱河市逮诲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌幽告,老刑警劉巖梅鹦,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異冗锁,居然都是意外死亡齐唆,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門冻河,熙熙樓的掌柜王于貴愁眉苦臉地迎上來箍邮,“玉大人,你說我怎么就攤上這事叨叙《П祝” “怎么了?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵摔敛,是天一觀的道長廷蓉。 經(jīng)常有香客問我,道長马昙,這世上最難降的妖魔是什么桃犬? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮行楞,結(jié)果婚禮上攒暇,老公的妹妹穿的比我還像新娘。我一直安慰自己子房,他們只是感情好形用,可當我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布就轧。 她就那樣靜靜地躺著,像睡著了一般田度。 火紅的嫁衣襯著肌膚如雪妒御。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天镇饺,我揣著相機與錄音乎莉,去河邊找鬼。 笑死奸笤,一個胖子當著我的面吹牛惋啃,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播监右,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼边灭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了健盒?” 一聲冷哼從身側(cè)響起绒瘦,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎味榛,沒想到半個月后椭坚,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體予跌,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡搏色,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了券册。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片频轿。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖烁焙,靈堂內(nèi)的尸體忽然破棺而出航邢,到底是詐尸還是另有隱情,我是刑警寧澤骄蝇,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布膳殷,位于F島的核電站,受9級特大地震影響九火,放射性物質(zhì)發(fā)生泄漏赚窃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一岔激、第九天 我趴在偏房一處隱蔽的房頂上張望勒极。 院中可真熱鬧,春花似錦虑鼎、人聲如沸辱匿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽匾七。三九已至絮短,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間昨忆,已是汗流浹背戚丸。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留扔嵌,地道東北人限府。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像痢缎,于是被迫代替她去往敵國和親胁勺。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,728評論 2 351

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