一翼岁、函數(shù)響應(yīng)式編程(FRP)
響應(yīng)式編程 簡稱 RP(Reactive Programming)蹦疑,它是一種面向數(shù)據(jù)流和變化傳播的編程方式。這意味著可以在編程語言中很方便地表達靜態(tài)或者動態(tài)的數(shù)據(jù)流顶籽,而相關(guān)的計算模型會自動將變化的值通過數(shù)據(jù)流進行傳播昔字。響應(yīng)式編程 與 函數(shù)式編程 相結(jié)合起來,就是 函數(shù)式響應(yīng)編程 FRP(Functional Reactive Programming)松邪。
前面在學(xué) RAC 的時候乎澄,已經(jīng)理解了函數(shù)響應(yīng)式編程思想,分別介紹了 函數(shù)式編程 與 響應(yīng)式編程 的特點测摔,這里就不再贅述置济。詳情可見《RAC(ReactiveCocoa) 初探》。下面要介紹的 RxSwift 就是利用的 FRP 思想锋八。如果有 Swift 語法不熟悉的可以先補習(xí)一下 Swift 語法浙于,我就惡補了一下 Swift 的閉包語法,并總結(jié)了一下挟纱,有需要的朋友也可以去看一下我的文章《Swift中的閉包》羞酗。
二、RxSwift
1紊服、簡介
ReactiveX(簡寫:Rx)是一個可以幫助我們簡化異步編程的框架檀轨。而 RxSwift 是 Rx 的 Swift 版本。除了 RxSwift欺嗤,還有 RxJava参萄、RxJS、Rx.Net 等煎饼,對應(yīng)的OC 版本則是 RAC(ReactiveCocoa)讹挎,這里是 RxSwift 的 github 地址 ,已經(jīng)有了將近 17000 顆星了。
RxSwift 的特點:
- 復(fù)合 - Rx 就是復(fù)合的代名詞
- 復(fù)用 - 因為它易復(fù)合
- 清晰 - 因為聲明都是不可變更的
- 易用 - 因為它抽象的了異步編程筒溃,使我們統(tǒng)一了代碼風(fēng)格
- 穩(wěn)定 - 因為 Rx 是完全通過單元測試的
2马篮、RxSwift 的導(dǎo)入
我采用的是 cocoaPods 的導(dǎo)入方式,在 Podfile 文件中寫如
# Podfile
use_frameworks!
target 'YOUR_TARGET_NAME' do
pod 'RxSwift', '~> 5.0'
pod 'RxCocoa', '~> 5.0'
end
替換 YOUR_TARGET_NAME 然后在 Podfile 目錄下, 終端輸入:
$ pod install
在項目中用到的地方引入即可
import RxSwift
import RxCocoa
3怜奖、RxSwift 的常用方式
現(xiàn)在我們通過了解幾個 RxSwift 的常用方式浑测,來了解一下它的強大之處吧!
(1) 按鈕點擊事件
傳統(tǒng)實現(xiàn)方法:
button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
func buttonTapped() {
print("button Tapped")
}
Rx 實現(xiàn):
button.rx.tap
.subscribe(onNext: {
print("button Tapped")
})
.disposed(by: disposeBag)
- 你不需要使用 Target Action歪玲,這樣使得代碼邏輯清晰可見尽爆。
(2) 代理
這里我們以 UIScrollViewDelegate 的偏移量代理方法為例,
傳統(tǒng)實現(xiàn)方法:
class ViewController: UIViewController {
...
override func viewDidLoad() {
super.viewDidLoad()
scrollView.delegate = self
}
}
extension ViewController: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
print("contentOffset: \(scrollView.contentOffset)")
}
}
Rx 實現(xiàn):
class ViewController: UIViewController {
...
override func viewDidLoad() {
super.viewDidLoad()
scrollView.rx.contentOffset
.subscribe(onNext: { contentOffset in
print("contentOffset: \(contentOffset)")
})
.disposed(by: disposeBag)
}
}
- 你不需要書寫代理的配置代碼读慎,就能獲得想要的結(jié)果漱贱。
(3) 通知
傳統(tǒng)實現(xiàn)方法:
var ntfObserver: NSObjectProtocol!
override func viewDidLoad() {
super.viewDidLoad()
ntfObserver = NotificationCenter.default.addObserver(
forName: .UIApplicationWillEnterForeground,
object: nil, queue: nil) { (notification) in
print("Application Will Enter Foreground")
}
}
deinit {
NotificationCenter.default.removeObserver(ntfObserver)
}
Rx 實現(xiàn):
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.rx
.notification(.UIApplicationWillEnterForeground)
.subscribe(onNext: { (notification) in
print("Application Will Enter Foreground")
})
.disposed(by: disposeBag)
}
- 你不需要去管理觀察者的生命周期,這樣你就有更多精力去關(guān)注業(yè)務(wù)邏輯夭委。
(4) timer 定時器
Rx 實現(xiàn):
func setupTimer() {
timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
timer.subscribe(onNext: { (num) in
print(num)
})
.disposed(by: disposeBag)
}
(5) 手勢
Rx 實現(xiàn):
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)
}
看了上面的的 Rx 實現(xiàn)方式幅狮,是不是覺得特別方便快捷。了解了用法株灸,我們再來深入了解一下 RxSwift 的核心吧崇摄。
4、RxSwift 的核心
Observable 是一個可監(jiān)聽的 Sequence(序列)慌烧。分為有窮序列和無窮序列逐抑,主要就是用來形成一條數(shù)據(jù)流。它有三種事件:next屹蚊、completed 和 error厕氨。
- next 事件主要是當(dāng) Observable 里出現(xiàn)新的數(shù)據(jù)時會發(fā)出的事件,同時該事件會攜帶新的數(shù)據(jù)對象汹粤。
- completed 事件是當(dāng) Observable 不再有新的數(shù)據(jù)出現(xiàn)命斧,Observable被標(biāo)記完成,并且將數(shù)據(jù)流終結(jié)嘱兼。
- error 事件是指當(dāng)數(shù)據(jù)流遇到了錯誤會發(fā)出的事件国葬,該事件也會導(dǎo)致 Observable 被終結(jié)。
下面是一個代碼實現(xiàn)的整個流程:
// 1:創(chuàng)建序列
// AnonymousObservable -> producer.subscriber -> run
let ob = Observable<Any>.create { (obserber) -> Disposable in
// 3:發(fā)送信號
obserber.onNext("發(fā)送信號")
obserber.onCompleted()
return Disposables.create()
}
// 2:訂閱信號
let _ = ob.subscribe(onNext: { (text) in
print("訂閱到:\(text)")
}, onError: { (error) in
print("錯誤: \(error)")
}, onCompleted: {
print("完成")
}) {
print("銷毀")
}
到此我們只是先對 RxSwift 進行了一次簡單的初探芹壕,了解了它的強大之處和簡單的用法汇四,以及它的核心原理。后面我還會更深一步去學(xué)習(xí)使用 RxSwift踢涌!
以上的總結(jié)參考了并部分摘抄了以下文章通孽,非常感謝以下作者的分享!:
1斯嚎、《RxSwift 中文文檔》
2利虫、作者Philm_iOS的《函數(shù)響應(yīng)式編程》
3挨厚、作者我只不過是出來寫寫代碼的《RAC(ReactiveCocoa)介紹(一)——基本介紹》
4堡僻、turtleeeee的《RxSwift的學(xué)習(xí)之路(一)——Observable》
轉(zhuǎn)載請備注原文出處糠惫,不得用于商業(yè)傳播——凡幾多