01.RxSwift-初識

做爲一個iOS開發人員, 當Swift趕上了RxSwift --> 函數響應式編程,在沒有認識RxSwift以前,多是一臉的懵逼,即便偶爾使用一下也是丈二的和尚莫不着頭腦,胡亂使用,可是當你認識瞭解並深刻探索之後,你會對RxSwift愛不釋手,甚至忘記最初代碼的寫法!!!!git

函數響應式編程
1. 函數式 :
  • 函數式編程不是一種技術,而是一種高級抽象的編程思想設計,簡稱FP(Functional Programming)函數一詞就直觀的體現了這就是一個數學運算方法。它又分爲兩種形式:
  • 無反作用:函數沒有變量,這種純粹的函數式編程語言,一旦輸入肯定,那麼輸出就是肯定的,它是沒有反作用的。
  • 有反作用:函數有變量,這種函數式編程語言它的輸入會隨着變量不斷的變化,最後的輸出也就不肯定,它是存在反作用的。

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

廢話很少說,直接實例感覺一把:編程

/**
1. 首先獲取 > 3的數字
2. 獲取的數字以後 + 1
3.全部數字中的偶數
*/
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)
         }
     }
  }
/**
  以上代碼看起來沒有任何問題,確實也毛病,可是:
  * 上面的代碼嵌套層次之深,讓人感受很是噁心
  * 代碼的可讀性也是很是差的
  * 代碼複用性較低
  * 維護以及代碼構建成本過高
*/

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

/**
  * 代碼層次很是清晰
  * 代碼可讀性高
  * 代碼複用性高
  * 代碼簡潔,直接面向開發需求
*/
複製代碼
2. 響應式 :
  • 響應式編程是一種基於異步數據流概念的編程模式。數據流就像一條河:它能夠被觀測,被過濾,被操做,或者爲新的消費者與另一條流合併爲一條新的流。響應式編程的一個關鍵概念是事件。事件能夠被等待,能夠觸發過程,也能夠觸發其它事件
  • 而iOS原生開發中,觸發對象與響應方法是分離的,如button的初始化和點擊響應方法是分離的。相似的還有taptextFieldtextViewnotifactionKVONSTimer等等。
RxSwift來源

RxSwiftRx家族 的重要一員,Rx就是複合的代名詞, 不只僅是一種使用可觀察數據流進行異步編程的接口,他更是一種編程思想理念的突破實踐。它集結了多種編程模式和精華於一身,包括:觀察者模式,迭代器,函數響應式編程等待。 RxSwift做爲Rx家族的一員,同樣繼承了Rx的這一系列的特性。swift

RxSwift優點
  • RxSwiftSwift函數響應式編程的一個開源庫:github地址, 其目的就是讓可觀察數據流、異步編程可以更好序列化,使用swift進行函數響應式編程。
  • 它拓展了觀察者模式,使你可以自由組合多個異步事件,而不須要去關心線程同步線程安全併發數據以及I/O阻塞
  • RxSwiftRxSwift 語言開發的一門函數響應式編程語言, 它能夠代替iOS系統的 Target Action,代理, 閉包,通知,KVO,同時還提供網絡,數據綁定,UI事件處理,UI的展現和更新,多線程……
RxSwift學習必要性
  • 複合 - Rx 就是和複合的代名詞
  • 復⽤用 - 復⽤用性⽐比較強 - 代碼量量下降
  • 清晰 - 由於聲明都是不不可變動更,代碼函數式編程可讀性強
  • 易易⽤用 - 理理解容易易,還抽象的了了異步編程,統⼀代碼⻛風格
  • 穩定 - 由於 Rx 是徹底經過單元測試的
RxSwift初識
1.KVO
//MARK: - KVO-原始三部曲
//1.添加觀察者
self.person.addObserver(self, forKeyPath: "name", options: .new, context: nil)

//2.實現觀察者方法
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        print("響應")
        print(change as Any)
  }
    
//3.移除觀察者
  deinit {
        self.person.removeObserver(self, forKeyPath: "name")
    }
複製代碼
//MARK: - RxSwift應用-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應用-button響應
 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應用-textfiled
func setupTextFiled() {
    // 咱們若是要對輸入的文本進行操做 - 好比輸入的的內容 而後咱們獲取裏面的偶數
    // self.textFiled.delegate = self
    // 感受是否是特別噁心
    // 下面咱們來看看Rx
    self.textFiled.rx.text.orEmpty.changed.subscribe(onNext: { (text) in
        print("監聽到了 - \(text)")
    }).disposed(by: disposeBag)
    
    self.textFiled.rx.text.bind(to: self.button.rx.title()).disposed(by: disposeBag)
}
複製代碼
  • UIScrollView
//MARK: - RxSwift應用-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應用-timer定時器
func setupTimer() {
    timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
    timer.subscribe(onNext: { (num) in
        print("hello word \(num)")
    }).disposed(by: disposeBag)
}
複製代碼
5.網絡
//MARK: - RxSwift應用-網絡請求
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層 須要設置代理或者addTarget,代碼邏輯與事件邏輯分層
  • 通知的實現,也是比較友善的:編程習慣都有在RxSwift風格里面保留,下降了開發門檻
  • 手勢看是去仍是很不爽,仍是須要添加到視圖上,可擴展一層再次處理,這樣就行了
  • Timer根據建立受RunLoop影響,還要手動銷燬,還可能有線程問題

Rx 之後:bash

  • RxSwift溫柔的一句代碼搞定,腰也不疼了,腿也不酸了,一口氣直接上6樓,timer還不受RunLoop影響了,也不用手動管理了,線程這些也都安全了
總結
  • 簡單的rx體驗,就能讓人感受,真的是到處皆rx,並且清晰簡潔,分段式操做,函數式響應。對比原始寫法,一個字爽~
  • 把函數響應式玩到了高潮!不管從代碼量,仍是從代碼的可讀性,抑或代碼的複用性......都是大大優化!
    圖片.png
相關文章
相關標籤/搜索