文章目錄
- 一 什么是RxSwift
- 二 RxSwift做了什么
- 2-1簡單介紹觀察者設計模式
- 2-1RxSwift做了什么
- 2-3 簡單理解Observable&Observer
- 三 RxSwift初級操作
- 3-1 監(jiān)聽事件
- 3-2 監(jiān)聽文本輸入框的文字改變
- 3-3 綁定數(shù)據(jù)賦值操作
- 3-4 KVO
- 四 RxSwift常見操作
- 4-1 never的obserable
- 4-2 empty的Obserable
- 4-3 just
- 4-4 of
- 4-5 from
- 4-6 create 自定義事件 開發(fā)中常用
- 4-7 range
- 4-8 repeat
- 五 RxSwift中的Subjects
- 5-1 Subjects 是什么?
- 5-2 PublishSubject
- 5-3 ReplySubject
- 5-4 BehaviorSubject
- 5-5 Variable
- 六 RxSwift中的變換操作
- 6-1 map
- 6-2 flatmap
- 七 資源的釋放
- 7-1 dispose
- 7-2 Dispose Bags
- 八 RxSwift下的UITableView的使用
一 什么是RxSwift
- RxSwift是Swift函數(shù)響應式編程的一個開源庫,由GitHub的ReactiveX組織開發(fā)和維護
- 其他語言像C#,Java 和JS也有: Rx.Net、RxJava、RxJS
- RxSwift的目的是讓數(shù)據(jù)/事件流和異步任務能夠更方便的序列化處理 能夠使用Swift進行響應式編程
二 RxSwift做了什么?
2-1 簡單介紹觀察者設計模式
- KVO,通知,甚至代理都是觀察者模式,在設計模式中他可是一個重中之重的設計模式
- 在我們iOS開發(fā)中 很多事件的監(jiān)聽都是通過觀察者設計模式進行監(jiān)聽的
2-2 RxSwift做了什么?
- RxSwift把我們程序中每一個操作都看成一個事件
- 比如一個TextFiled中的文本改變,一個按鈕的點擊,或者一個網(wǎng)絡請求結束等,每一個事件源就可以看成一個管道,也就是Sequence
- 比如一個TextFiled,當我們改變里邊的文本的時候 這個時候TextFiled就會不斷的發(fā)出事件, 從他的Sequence中不斷的流出 我們只需要監(jiān)聽這個Sequence,每流出一個事件 就做相應的處理
- 同理UIButton 也是一個Sequence 每點擊一次就流出一個事件

2-3 簡單理解Observable&Observer

三RxSwift初級操作
3-1 監(jiān)聽事件
// 1 監(jiān)聽按鈕點擊
// 要用局部的按鈕 方便提示 之所以在這里備用一個局部按鈕 是因為RxSwift 有什么提示很不好 局部變量就可以解決這個問題
// let button = UIButton();
btn1.rx.tap.subscribe { (event : Event<()>) in
print("我是按鈕我被點擊了")
}.addDisposableTo(bag)
3-2 監(jiān)聽文本輸入框的文字改變
// 2.1 第一種方式
textFlied.rx.text.subscribe { (event : Event<String?>) in
// element 取出這個元素 取出來的是可選類型中的可選類型 可以解包兩次
print(event.element!!)
}.addDisposableTo(bag)
// 2.1 第二種方式 onNext
textFlied.rx.text.subscribe(onNext: { (str : String?) in
print(str!)
}).addDisposableTo(bag)
3-3 綁定數(shù)據(jù)賦值操作
// 老套的做法
textFlied.rx.text.subscribe(onNext: { (str : String?) in
self.label.text = str!
}).addDisposableTo(bag)
// RxSwift推薦的做法 .bind(to: <#T##ObserverType#>) observerType 是一個協(xié)議 而UIbindObser遵守了這個協(xié)議
textFlied.rx.text.bind(to: label.rx.text).addDisposableTo(bag)
3-4 KVO
// KVO 傳統(tǒng)的做法
// 1 監(jiān)聽屬性
lbl.addObserver(self, forKeyPath: "text", options: .new, context: nil)
// 2 代理方法
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
print((change?[NSKeyValueChangeKey.newKey])!)
}
// RxSwift 的做法
label.rx.observe(String.self, "text").subscribe(onNext: { (str : String?) in
print(str!)
}).addDisposableTo(bag)
label.rx.observe(CGRect.self, "frame").subscribe(onNext: { (frame : CGRect?) in
print(frame!)
}).addDisposableTo(bag)
四 RxSwift常見操作
4-1 never的obserable
// 創(chuàng)建一個naver的obserable 從來不執(zhí)行
let neverO = Observable<String>.never()
neverO.subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
4-2 empty的Obserable 只發(fā)出complete事件
// 創(chuàng)建一個empty的Obserable 只能發(fā)出一個complete事件
let empty = Observable<String>.empty()
empty.subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
4-3 just
// just是創(chuàng)建一個sequence只能發(fā)出一種特定的事件 能正常結束
let just = Observable.just("10")
just.subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
4-4 of
//創(chuàng)建一個sequence 能發(fā)出很多事件信號
let of = Observable.of("a","b","c")
of.subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
4-5 from
// from就是從數(shù)組中創(chuàng)建sequence
let from = Observable.from(["1","2","3"])
from.subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
4-6 create 自定義事件 開發(fā)中常用
// create 創(chuàng)建一個自定義的disposable 實際開發(fā)中常用的 會在自定義很多事件來監(jiān)聽的
let create = createObserable()
create.subscribe { (event : Event<Any>) in
print(event)
}.addDisposableTo(bag)
// 方法
func createObserable() -> Observable<Any> {
return Observable.create({ (observer : AnyObserver<Any>) -> Disposable in
observer.onNext("奧卡姆剃須刀")
observer.onNext("18")
observer.onNext("65")
observer.onCompleted()
return Disposables.create()
})
}
// 自定義just
let myJust = myJustObservable(element: "奧卡姆剃須刀")
myJust.subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
// 方法
func myJustObservable(element:String) -> Observable<String> {
return Observable.create({ (observer : AnyObserver<String>) -> Disposable in
observer.onNext(element)
observer.onCompleted()
return Disposables.create()
})
}
4-7 range 這個作用不是很大
let range = Observable.range(start: 1, count: 10)
range.subscribe { (event : Event<Int>) in
print(event)
}.addDisposableTo(bag)
4-8 repeat
let repeatLL = Observable.repeatElement("奧卡姆剃須刀")
// 重復次數(shù)
repeatLL.take(5).subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
五 RxSwift中的Subjects
5-1 Subjects 是什么?
Subjects 是Observable 和 Observer 之間的橋梁, 一個subject 既是一個Obserable 也是一個 Observer 他既可以發(fā)出事件,也可以監(jiān)聽事件
5-2 PublishSubject
當你訂閱PublishSubject的時候,你只能接受訂閱他之后發(fā)生的事件,subject.onNext() 發(fā)出onNext事件,對應的還有onError() 和onCompleted() 事件
// 1 publishSubject 訂閱者只能接受,訂閱之后的事件 也就是必須先訂閱 再發(fā)送事件
let publishSub = PublishSubject<String>()
publishSub.subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
publishSub.onNext("奧卡姆剃須刀")
5-3 ReplySubject
ReplySubject 當你訂閱ReplySubject 的時候,你可以接收到訂閱他之后的事件,但也可以接收訂閱他之前發(fā)出的事件 ,接收幾個事件取決于bufferSize的大小 會接收最后發(fā)送的信號
// 限制兩個信號
// let replySub = ReplaySubject<String>.create(bufferSize: 2)
// 沒有限制的replySubject
let replySub = ReplaySubject<String>.createUnbounded()
replySub.onNext("1")
replySub.onNext("2")
replySub.onNext("3")
replySub.onNext("4")
replySub.subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
replySub.onNext("5")
5-4 BehaviorSubject
當你訂閱了BehaviorSubject 你就會接收到訂閱之前的最后一個事件 可以初始化的時候就給一個訂閱值
這個用的是最多的 一般用法是初始的時候給一個默認數(shù)據(jù) 然后進行刷新加載更多數(shù)據(jù)
let behaviorSub = BehaviorSubject(value: "10")
behaviorSub.onNext("a")
// 只能訂閱到 b
behaviorSub.onNext("b")
behaviorSub.subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
behaviorSub.onNext("11")
behaviorSub.onNext("12")
behaviorSub.onNext("13")
5-5 Variable
1 Variable 是BehaviorSubject 一個包裝箱 就像是一個箱子一樣 使用的時候需要調用asObservable() 拆箱,里面的Value 是一個BehaviorSubject
2 如果 Variable 打算發(fā)出事件 直接修改對象的Value即可
3 當事件結束的時候 Variable 會自動發(fā)出complete事件
let variable = Variable("a")
// 要是想修改值 直接修改value就好
variable.value = "b"
variable.asObservable().subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
// 也能發(fā)出事件
variable.value = "c"
variable.value = "d"
六 RxSwift中的變換操作
6-1 map
通過傳入一個函數(shù)閉包把原來的sequence轉變?yōu)橐粋€新的sequence的操作
// 1 swift中map的使用
let array = [1,2,3,4]
let arr2 = array.map { (num : Int) -> Int in
return num * num
}
print(arr2)
// 2 swift的函數(shù)式編程 用的還是比較少的 還是習慣于面向對象的方式
let arr3 = array.map({ $0 * $0 })
print(arr3)
// 3 rxswift 中map函數(shù)的使用
Observable.of(10,11,12,13)
.map { (num : Int) -> Int in
return num * num
}.subscribe { (event : Event<Int>) in
print(event)
}.addDisposableTo(bag)
6-2 flatmap
將一個sequence轉換成sequences。 當你接受一個sequence事件,你還想接受其他sequence發(fā)出的事件的話 可以使用flatmap,他會將每一個sequence事件進行處理后 然后再以一個sequence形式發(fā)出事件
// 1 先定義一個結構體
// RxSwift的思想 讓任何一個變量都是可以監(jiān)聽的
struct Student {
var score : Variable<Double>
}
// 3 flatmap 的使用 映射 Observable的
let stu1 = Student(score: Variable(100))
let stu2 = Student(score: Variable(99))
let stu3 = Student(score: Variable(98))
// 鏈式編程思維
let studentVariable = Variable(stu1)
// 這個方法會把所有的是都監(jiān)聽到 都打印 但常常我們只關心最新的一個訂閱
// studentVariable.asObservable().flatMap { (stu : Student) -> Observable<Double> in
// return stu.score.asObservable()
// }.subscribe { (event : Event<Double>) in
// print(event)
// }.addDisposableTo(bag)
// 常用的是這一個方法 會先打印一下初始化的數(shù)據(jù) 只會關心最新訂閱值的改變
studentVariable.asObservable().flatMapLatest { (stu : Student) -> Observable<Double> in
return stu.score.asObservable()
}.subscribe { (event : Event<Double>) in
print(event)
}.addDisposableTo(bag)
studentVariable.value = stu2
stu2.score.value = 0
// 這樣的話每一個值的改變都會發(fā)送信號
// 我已經(jīng)不關心你的值的改變 我只關心最新的訂閱的值的變化
stu1.score.value = 1000;
七 資源的釋放
- 當監(jiān)聽一個事件序列的時候,有消息事件來了,我們做某些事情,但是這個事件序列不在發(fā)出消息了,我們的監(jiān)聽也就沒有什么存在價值了,所以我們需要釋放我們這些監(jiān)聽資源,其實也就是每種編程語言中的內(nèi)存資源釋放,
- OC 和Swift 也一樣,在你不需要某些變量的時候,你需要吧這些變量所占用的內(nèi)存空間釋放掉,
- 釋放某一個監(jiān)聽的時候,我們可以手動調用釋放方法
7-1 dispose
相當于MRC中手動調用release操作
-
注意:因為觀察者已經(jīng)銷毀,所以后面無法接受事件
// 1 dispose() 讓對象立即銷毀掉 后邊在改變值的時候 此對象已經(jīng)銷毀了 let variable1 = Variable("奧卡姆剃須刀") variable1.asObservable().subscribe { (event : Event<String>) in print(event) }.dispose()
7-2 Dispose Bags
- 除了上邊手動的方法 還有一種自動的方式 推薦使用這種方式 這種方式就好像iOS中的ARC方式 會自動去釋放資源
// 2 DisposeBag
fileprivate lazy var bag : DisposeBag = DisposeBag()
let subject = BehaviorSubject(value: "a")
subject.subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
八 RxSwift下的UITableView的使用
// VC 中的代碼
//1.創(chuàng)建UITableView(跟OC幾乎一樣)
let tabV = UITableView(frame: view.bounds, style: UITableViewStyle.plain)
tableView = tabV
//2.注冊Cell
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellID)
self.view.addSubview(tableView)
// 負責數(shù)據(jù)綁定 傳回來row model 和 cell 自行復制
viewModel.modelObserable.asObservable()
.bind(to: tableView.rx.items(cellIdentifier: cellID,
cellType: UITableViewCell.self)){ row, model, cell in
cell.textLabel?.text = model.name
}.addDisposableTo(bag)
// 監(jiān)聽點擊cell 獲取index
tabV.rx.itemSelected.subscribe(onNext: { (index : IndexPath) in
// 點擊cell就刷新數(shù)據(jù)
// self.reloadData()
}).addDisposableTo(bag)
// 監(jiān)聽點擊cell 獲取Model
tabV.rx.modelSelected(RxModel.self).subscribe(onNext: { (model : RxModel) in
print(model.name)
}).addDisposableTo(bag)
VIewModel中的代碼
var modelObserable : Variable<[RxModel]> = {
var models : [RxModel] = [RxModel]()
for i in 0..<20 {
let model = RxModel()
model.name = "我是小\(i)"
models.append(model)
}
return Variable(models)
}()
本文代碼Demo
《多次更新完結》