RxSwift 個人學習筆記記錄

文章目錄

  • 一 什么是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 每點擊一次就流出一個事件
image.png
2-3 簡單理解Observable&Observer
image.png

三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

《多次更新完結》

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容