01.RxSwift-初識

作為一個iOS開發(fā)人員, 當Swift遇上了RxSwift --> 函數(shù)響應(yīng)式編程,在沒有認識RxSwift之前,可能是一臉的懵逼,即使偶爾使用一下也是丈二的和尚莫不著頭腦,胡亂使用,但是當你認識了解并深入探索以后,你會對RxSwift愛不釋手,甚至忘記最初代碼的寫法!?。?!

函數(shù)響應(yīng)式編程
1. 函數(shù)式 :
  • 函數(shù)式編程不是一種技術(shù),而是一種高級抽象的編程思想設(shè)計,簡稱FP(Functional Programming),函數(shù)一詞就直觀的體現(xiàn)了這就是一個數(shù)學(xué)運算方法。它又分為兩種形式:
  • 無副作用:函數(shù)沒有變量,這種純粹的函數(shù)式編程語言,一旦輸入確定,那么輸出就是確定的,它是沒有副作用的。
  • 有副作用:函數(shù)有變量,這種函數(shù)式編程語言它的輸入會隨著變量不斷的變化,最后的輸出也就不確定,它是存在副作用的。

函數(shù)表達式 : y = f(x) ---> x = f(x) ---> y = f(f(x))

廢話不多說,直接實例感受一把:

/**
1. 首先獲取 > 3的數(shù)字
2. 獲取的數(shù)字之后 + 1
3.所有數(shù)字中的偶數(shù)
*/
let array = [1,2,3,4,5,6,7,8,9,10]
for num in array{
  if num > 3{
       let number = num + 1
        if (number % 2 == 0) {
            print(number)
         }
     }
  }
/**
  以上代碼看起來沒有任何問題,確實也毛病,但是:
  * 上面的代碼嵌套層次之深,讓人感覺非常惡心
  * 代碼的可讀性也是非常差的
  * 代碼復(fù)用性較低
  * 維護以及代碼構(gòu)建成本太高
*/

//這樣就成了函數(shù)式出現(xiàn)的必要性:
array.filter{ $0 > 3}
            .filter{ ($0+1) % 2 == 0 }
            .forEach { print($0) }

/**
  * 代碼層次非常清晰
  * 代碼可讀性高
  * 代碼復(fù)用性高
  * 代碼簡潔,直接面向開發(fā)需求
*/
2. 響應(yīng)式 :
  • 響應(yīng)式編程是一種基于異步數(shù)據(jù)流概念的編程模式。數(shù)據(jù)流就像一條河:它可以被觀測,被過濾,被操作,或者為新的消費者與另外一條流合并為一條新的流。響應(yīng)式編程的一個關(guān)鍵概念是事件。事件可以被等待,可以觸發(fā)過程,也可以觸發(fā)其它事件
  • 而iOS原生開發(fā)中,觸發(fā)對象與響應(yīng)方法是分離的,如button的初始化和點擊響應(yīng)方法是分離的。類似的還有taptextField、textViewnotifaction、KVO、NSTimer等等。
RxSwift來源

RxSwiftRx家族 的重要一員,Rx就是復(fù)合的代名詞, 不僅僅是一種使用可觀察數(shù)據(jù)流進行異步編程的接口,他更是一種編程思想理念的突破實踐。它集結(jié)了多種編程模式和精華于一身,包括:觀察者模式,迭代器,函數(shù)響應(yīng)式編程等待。 RxSwift作為Rx家族的一員,一樣繼承了Rx的這一系列的特性。

RxSwift優(yōu)勢
  • RxSwiftSwift函數(shù)響應(yīng)式編程的一個開源庫:github地址, 其目的就是讓可觀察數(shù)據(jù)流、異步編程能夠更好序列化,使用swift進行函數(shù)響應(yīng)式編程。
  • 它拓展了觀察者模式,使你能夠自由組合多個異步事件,而不需要去關(guān)心線程,同步,線程安全,并發(fā)數(shù)據(jù)以及I/O阻塞
  • RxSwiftRxSwift 語言開發(fā)的一門函數(shù)響應(yīng)式編程語言, 它可以代替iOS系統(tǒng)的 Target Action,代理, 閉包,通知,KVO,同時還提供網(wǎng)絡(luò),數(shù)據(jù)綁定,UI事件處理,UI的展示和更新,多線程……
RxSwift學(xué)習(xí)必要性
  • 復(fù)合 - Rx 就是和復(fù)合的代名詞
  • 復(fù)?用 - 復(fù)?用性?比較強 - 代碼量量降低
  • 清晰 - 因為聲明都是不不可變更更,代碼函數(shù)式編程可讀性強
  • 易易?用 - 理理解容易易,還抽象的了了異步編程,統(tǒng)?代碼?風(fēng)格
  • 穩(wěn)定 - 因為 Rx 是完全通過單元測試的
RxSwift初識
1.KVO
//MARK: - KVO-原始三部曲
//1.添加觀察者
self.person.addObserver(self, forKeyPath: "name", options: .new, context: nil)

//2.實現(xiàn)觀察者方法
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        print("響應(yīng)")
        print(change as Any)
  }
    
//3.移除觀察者
  deinit {
        self.person.removeObserver(self, forKeyPath: "name")
    }
//MARK: - RxSwift應(yīng)用-KVO
func setupKVO() {
        self.person.rx.observeWeakly(String.self, "name")
            .subscribe(onNext: { (value) in
                print(value as Any)
            })
            .disposed(by: disposeBag)
    }
2.UI層
  • UIButton
//MARK: - button原始是寫法
self.button.addTarget(self, action: #selector(click), for: .touchUpInside)

func click() {
  print("點擊")
}
 //MARK: - RxSwift應(yīng)用-button響應(yīng)
 func setupButton() {
  self.button.rx.tap
     .subscribe(onNext: { () in
         print("點擊來了")
     })
     .disposed(by: disposeBag)
//上面的代碼和下面的意思一樣
   self.button.rx.controlEvent(.touchUpInside)
            .subscribe(onNext: { () in
                print("點擊了")
            })
            .disposed(by: disposeBag)
}
  • UITextFiled
//MARK: - RxSwift應(yīng)用-textfiled
func setupTextFiled() {
    // 我們?nèi)绻獙斎氲奈谋具M行操作 - 比如輸入的的內(nèi)容 然后我們獲取里面的偶數(shù)
    // self.textFiled.delegate = self
    // 感覺是不是特別惡心
    // 下面我們來看看Rx
    self.textFiled.rx.text.orEmpty.changed.subscribe(onNext: { (text) in
        print("監(jiān)聽到了 - \(text)")
    }).disposed(by: disposeBag)
    
    self.textFiled.rx.text.bind(to: self.button.rx.title()).disposed(by: disposeBag)
}
  • UIScrollView
//MARK: - RxSwift應(yīng)用-scrollView
func setupScrollerView() {
        scrollView.rx.contentOffset
            .subscribe(onNext: { [weak self](content) in
                self?.view.backgroundColor = UIColor.init(red: content.y/255*0.8, green: content.y/255*0.6, blue: content.y/255*0.3, alpha: 1)
            })
        .disposed(by: disposeBag)
    }
  • Tap手持
 //MARK: - 手勢
func setupGestureRecognizer(){
        let tap = UITapGestureRecognizer()
        self.label.addGestureRecognizer(tap)
        self.label.isUserInteractionEnabled = true
        tap.rx.event.subscribe(onNext: { (tap) in
            print(tap.view)
        })
        .disposed(by: disposeBag)
    }
3.通知
//MARK: - 通知
func setupNotification(){
    NotificationCenter.default.rx
        .notification(UIResponder.keyboardWillShowNotification)
        .subscribe { (event) in
            print(event)
    }.disposed(by: disposeBag)
}
4.NSTimer
//MARK: - RxSwift應(yīng)用-timer定時器
func setupTimer() {
    timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
    timer.subscribe(onNext: { (num) in
        print("hello word \(num)")
    }).disposed(by: disposeBag)
}
5.網(wǎng)絡(luò)
//MARK: - RxSwift應(yīng)用-網(wǎng)絡(luò)請求
func setupNextwork() {
    let url = URL(string: "https://www.baidu.com")
    URLSession.shared.rx.response(request: URLRequest(url: url!))
        .subscribe(onNext: { (response, data) in
            print("response ==== \(response)")
            print("data ===== \(data)")
        }, onError: { (error) in
            print("error ===== \(error)")
        }).disposed(by: disposeBag)
}

Rx 以前:

  • KVO三部曲很惡心,不直觀
  • UI層 需要設(shè)置代理或者addTarget,代碼邏輯與事件邏輯分層
  • 通知的實現(xiàn),也是比較友善的:編程習(xí)慣都有在RxSwift風(fēng)格里面保留,降低了開發(fā)門檻
  • 手勢看是去還是很不爽,還是需要添加到視圖上,可擴展一層再次處理,這樣就好了
  • Timer根據(jù)創(chuàng)建受RunLoop影響,還要手動銷毀,還可能有線程問題

Rx 以后:

  • RxSwift溫柔的一句代碼搞定,腰也不疼了,腿也不酸了,一口氣直接上6樓,timer還不受RunLoop影響了,也不用手動管理了,線程這些也都安全了
總結(jié)
  • 簡單的rx體驗,就能讓人感覺,真的是處處皆rx,而且清晰簡潔,分段式操作,函數(shù)式響應(yīng)。對比原始寫法,一個字爽~
  • 把函數(shù)響應(yīng)式玩到了高潮!無論從代碼量,還是從代碼的可讀性,抑或代碼的復(fù)用性......都是大大優(yōu)化!


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

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

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