就問此時此刻還有誰?45度仰望天空,該死!我這無處安放的魅力!swift
- RxSwift(1)— 初探
- RxSwift(2)— 核心邏輯源碼分析
- RxSwift(3)— Observable序列的建立方式
- RxSwift(4)— 高階函數(上)
- RxSwift(5)— 高階函數(下)
- RxSwift(6)— 調度者-scheduler源碼解析(上)
- RxSwift(7)— 調度者-scheduler源碼解析(下)
- RxSwift(8)— KVO底層探索(上)
- RxSwift(9)— KVO底層探索(下)
- RxSwift(10)— 場景序列總結
- RxSwift(11)— dispose源碼解析
- RxSwift(12)— Subject即攻也守
- RxSwift(13)— 爬過的坑
- RxSwift(14)— MVVM雙向綁定
RxSwift 目錄直通車 --- 和諧學習,不急不躁!數組
由於
RxSwift
,咱們遊刃在函數響應式的世界裏!若是你想玩得更爽,那麼這一篇RxSwift-高階函數
對你來講是必需要掌握的內容!只有你玩好了高階函數才能在實際開發中真正地享受:萬物皆Rx網絡
print("*****startWith*****")
Observable.of("1", "2", "3", "4")
.startWith("A")
.startWith("B")
.startWith("C", "a", "b")
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
//效果: CabBA1234
複製代碼
print("*****merge*****")
let subject1 = PublishSubject<String>()
let subject2 = PublishSubject<String>()
// merge subject1和subject2
Observable.of(subject1, subject2)
.merge()
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
subject1.onNext("C")
subject1.onNext("o")
subject2.onNext("o")
subject2.onNext("o")
subject1.onNext("c")
subject2.onNext("i")
// Cooci - 任何一個響應都會勾起新序列響應
複製代碼
print("*****zip*****")
let stringSubject = PublishSubject<String>()
let intSubject = PublishSubject<Int>()
Observable.zip(stringSubject, intSubject) { stringElement, intElement in
"\(stringElement) \(intElement)"
}
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
stringSubject.onNext("C")
stringSubject.onNext("o") // 到這裏存儲了 C o 可是不會響應除非;另外一個響應
intSubject.onNext(1) // 勾出一個
intSubject.onNext(2) // 勾出另外一個
stringSubject.onNext("i") // 存一個
intSubject.onNext(3) // 勾出一個
// 說白了: 只有兩個序列同時有值的時候纔會響應,不然存值
複製代碼
print("*****combineLatest*****")
let stringSub = PublishSubject<String>()
let intSub = PublishSubject<Int>()
Observable.combineLatest(stringSub, intSub) { strElement, intElement in
"\(strElement) \(intElement)"
}
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
stringSub.onNext("L") // 存一個 L
stringSub.onNext("G") // 存了一個覆蓋 - 和zip不同
intSub.onNext(1) // 發現strOB也有G 響應 G 1
intSub.onNext(2) // 覆蓋1 -> 2 發現strOB 有值G 響應 G 2
stringSub.onNext("Cooci") // 覆蓋G -> Cooci 發現intOB 有值2 響應 Cooci 2
// combineLatest 比較zip 會覆蓋
// 應用很是頻繁: 好比帳戶和密碼同時知足->才能登錄. 不關係帳戶密碼怎麼變化的只要查看最後有值就能夠 loginEnable
複製代碼
print("*****switchLatest*****")
let switchLatestSub1 = BehaviorSubject(value: "L")
let switchLatestSub2 = BehaviorSubject(value: "1")
let switchLatestSub = BehaviorSubject(value: switchLatestSub1)// 選擇了 switchLatestSub1 就不會監聽 switchLatestSub2
switchLatestSub.asObservable()
.switchLatest()
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
switchLatestSub1.onNext("G")
switchLatestSub1.onNext("_")
switchLatestSub2.onNext("2")
switchLatestSub2.onNext("3") // 2-3都會不會監聽,可是默認保存由 2覆蓋1 3覆蓋2
switchLatestSub.onNext(switchLatestSub2) // 切換到 switchLatestSub2
switchLatestSub1.onNext("*")
switchLatestSub1.onNext("Cooci") // 原理同上面 下面若是再次切換到 switchLatestSub1會打印出 Cooci
switchLatestSub2.onNext("4")
複製代碼
combineLatest
底層原理來分析self._arity = arity
這就是咱們這次管理的序列個數self._hasValue
就是一個初始化的個數爲arity
的,裏面的值都是false
,只有爲何這麼初始化後面會講的!next(_ index: Int)
方法中,判斷self._hasValue[index]
就是咱們的剛剛初始化的集合,第一次進來就是第一個序列,進來就會標記true
,而且_numberOfValues+1
,此時就是0->1
_numberOfValues < arity
就會跳過true
,而且_numberOfValues+1
,此時就是1->2
self._numberOfValues == self._arity
,取回let result = try self.getResult()
響應結果,而後就發送出去:self.forwardOn(.next(result))
combineLatest
必須兩個序列都響應纔會響應最終的結果print("*****map*****")
let ob = Observable.of(1,2,3,4)
ob.map { (number) -> Int in
return number+2
}
.subscribe{
print("\($0)")
}
.disposed(by: disposeBag)
複製代碼
flatMap
和flatMapLatest
的區別是,flatMapLatest
只會從最近的內部可觀測序列發射元素print("*****flatMap*****")
let boy = LGPlayer(score: 100)
let girl = LGPlayer(score: 90)
let player = BehaviorSubject(value: boy)
player.asObservable()
.flatMap { $0.score.asObservable() } // 自己score就是序列 模型就是序列中的序列
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
boy.score.onNext(60)
player.onNext(girl)
boy.score.onNext(50)
boy.score.onNext(40)// 若是切換到 flatMapLatest 就不會打印
girl.score.onNext(10)
girl.score.onNext(0)
複製代碼
flatMapLatest
其實是map
和switchLatest
操做符的組合print("*****scan*****")
Observable.of(10, 100, 1000)
.scan(2) { aggregateValue, newValue in
aggregateValue + newValue // 10 + 2 , 100 + 10 + 2 , 1000 + 100 + 2
}
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
// 這裏主要強調序列值之間的關係
複製代碼
map
來進行分析composeMap
建立中間序列:Mapself._source = source
& self._transform = transform
保存源序列和外界傳進去的映射表達式:$0+2
MapSink
調用on(_ event: Event<SourceType>)
來發送信號,發送信號以前let mappedElement = try self._transform(element)
取出要發送的結果,就是通過映射表達式處理的結果self.forwardOn(.next(mappedElement))
正常發送print("*****filter*****")
Observable.of(1,2,3,4,5,6,7,8,9,0)
.filter { $0 % 2 == 0 }
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
複製代碼
print("*****distinctUntilChanged*****")
Observable.of("1", "2", "2", "2", "3", "3", "4")
.distinctUntilChanged()
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
複製代碼
print("*****elementAt*****")
Observable.of("C", "o", "o", "c", "i")
.elementAt(3)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
複製代碼
print("*****single*****")
Observable.of("Cooci", "Kody")
.single()
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
Observable.of("Cooci", "Kody")
.single { $0 == "Kody" }
.subscribe { print($0) }
.disposed(by: disposeBag)
複製代碼
print("*****take*****")
Observable.of("Hank", "Kody","Cooci", "CC")
.take(2)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
複製代碼
print("*****takeLast*****")
Observable.of("Hank", "Kody","Cooci", "CC")
.takeLast(3)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
複製代碼
print("*****takeWhile*****")
Observable.of(1, 2, 3, 4, 5, 6)
.takeWhile { $0 < 3 }
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
複製代碼
print("*****takeUntil*****")
let sourceSequence = PublishSubject<String>()
let referenceSequence = PublishSubject<String>()
sourceSequence
.takeUntil(referenceSequence)
.subscribe { print($0) }
.disposed(by: disposeBag)
sourceSequence.onNext("Cooci")
sourceSequence.onNext("Kody")
sourceSequence.onNext("CC")
referenceSequence.onNext("Hank") // 條件一出來,下面就走不了
sourceSequence.onNext("Lina")
sourceSequence.onNext("小雁子")
sourceSequence.onNext("婷婷")
複製代碼
textfiled
都會有默認序列產生print("*****skip*****")
Observable.of(1, 2, 3, 4, 5, 6)
.skip(2)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
print("*****skipWhile*****")
Observable.of(1, 2, 3, 4, 5, 6)
.skipWhile { $0 < 4 }
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
複製代碼
print("*****skipUntil*****")
let sourceSeq = PublishSubject<String>()
let referenceSeq = PublishSubject<String>()
sourceSeq
.skipUntil(referenceSeq)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
// 沒有條件命令 下面走不了
sourceSeq.onNext("Cooci")
sourceSeq.onNext("Kody")
sourceSeq.onNext("CC")
referenceSeq.onNext("Hank") // 條件一出來,下面就能夠走了
sourceSeq.onNext("Lina")
sourceSeq.onNext("小雁子")
sourceSeq.onNext("婷婷")
複製代碼
print("*****toArray*****")
Observable.range(start: 1, count: 10)
.toArray()
.subscribe { print($0) }
.disposed(by: disposeBag)
複製代碼
scan
print("*****reduce*****")
Observable.of(10, 100, 1000)
.reduce(1, accumulator: +) // 1 + 10 + 100 + 1000 = 1111
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
複製代碼
print("*****concat*****")
let subject1 = BehaviorSubject(value: "Hank")
let subject2 = BehaviorSubject(value: "1")
let subjectsSubject = BehaviorSubject(value: subject1)
subjectsSubject.asObservable()
.concat()
.subscribe { print($0) }
.disposed(by: disposeBag)
subject1.onNext("Cooci")
subject1.onNext("Kody")
subjectsSubject.onNext(subject2)
subject2.onNext("打印不出來")
subject2.onNext("2")
subject1.onCompleted() // 必需要等subject1 完成了才能訂閱到! 用來控制順序 網絡數據的異步
subject2.onNext("3")
複製代碼
因爲篇幅緣由,這篇博客先寫到這裏,高階函數的用法仍是有點意思的!若是你是一個
RxSwift
新手,仍是很是建議你們耐着性子好好練習,對你的開發絕對有幫助 請繼續觀看下一篇博客 RxSwift-高階函數(下)閉包就問此時此刻還有誰?45度仰望天空,該死!我這無處安放的魅力!app