做爲一個iOS開發人員, 當
Swift
趕上了RxSwift
--> 函數響應式編程,在沒有認識RxSwift
以前,多是一臉的懵逼,即便偶爾使用一下也是丈二的和尚莫不着頭腦,胡亂使用,可是當你認識瞭解並深刻探索之後,你會對RxSwift
愛不釋手,甚至忘記最初代碼的寫法!!!!git
函數式編程
不是一種技術,而是一種高級抽象的編程思想設計,簡稱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) }
/**
* 代碼層次很是清晰
* 代碼可讀性高
* 代碼複用性高
* 代碼簡潔,直接面向開發需求
*/
複製代碼
響應式編程
是一種基於異步數據流概念的編程模式。數據流就像一條河:它能夠被觀測,被過濾,被操做,或者爲新的消費者與另一條流合併爲一條新的流。響應式編程的一個關鍵概念是事件。事件能夠被等待,能夠觸發過程,也能夠觸發其它事件button
的初始化和點擊響應方法是分離的。相似的還有tap
、textField
、textView
、notifaction
、KVO
、NSTimer
等等。RxSwift
是 Rx家族 的重要一員,Rx
就是複合的代名詞, 不只僅是一種使用可觀察數據流進行異步編程的接口,他更是一種編程思想理念的突破實踐。它集結了多種編程模式和精華於一身,包括:觀察者模式,迭代器,函數響應式編程等待。 RxSwift
做爲Rx
家族的一員,同樣繼承了Rx
的這一系列的特性。swift
RxSwift
是Swift
函數響應式編程的一個開源庫:github地址, 其目的就是讓可觀察數據流、異步編程可以更好序列化,使用swift
進行函數響應式編程。關心線程
,同步
,線程安全
,併發數據以及I/O阻塞
。RxSwift
是 Rx
爲 Swift
語言開發的一門函數響應式編程語言, 它能夠代替iOS系統的 Target Action
,代理
, 閉包
,通知
,KVO
,同時還提供網絡
,數據綁定
,UI事件處理
,UI的展現和更新
,多線程
……
- 複合 - Rx 就是和複合的代名詞
- 復⽤用 - 復⽤用性⽐比較強 - 代碼量量下降
- 清晰 - 由於聲明都是不不可變動更,代碼函數式編程可讀性強
- 易易⽤用 - 理理解容易易,還抽象的了了異步編程,統⼀代碼⻛風格
- 穩定 - 由於 Rx 是徹底經過單元測試的
//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)
}
複製代碼
//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)
}
複製代碼
//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)
}
複製代碼
//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)
}
複製代碼
//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)
}
複製代碼
//MARK: - 通知
func setupNotification(){
NotificationCenter.default.rx
.notification(UIResponder.keyboardWillShowNotification)
.subscribe { (event) in
print(event)
}.disposed(by: disposeBag)
}
複製代碼
//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)
}
複製代碼
//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
,並且清晰簡潔,分段式操做,函數式響應。對比原始寫法,一個字爽~- 把函數響應式玩到了高潮!不管從代碼量,仍是從代碼的可讀性,抑或代碼的複用性......都是大大優化!
![]()