一、函數(shù)響應(yīng)式編程(FRP)
響應(yīng)式編程 簡(jiǎn)稱 RP(Reactive Programming),它是一種面向數(shù)據(jù)流和變化傳播的編程方式。這意味著可以在編程語(yǔ)言中很方便地表達(dá)靜態(tài)或者動(dòng)態(tài)的數(shù)據(jù)流,而相關(guān)的計(jì)算模型會(huì)自動(dòng)將變化的值通過(guò)數(shù)據(jù)流進(jìn)行傳播。響應(yīng)式編程 與 函數(shù)式編程 相結(jié)合起來(lái),就是 函數(shù)式響應(yīng)編程 FRP(Functional Reactive Programming)。
前面在學(xué) RAC 的時(shí)候,已經(jīng)理解了函數(shù)響應(yīng)式編程思想,分別介紹了 函數(shù)式編程 與 響應(yīng)式編程 的特點(diǎn),這里就不再贅述。詳情可見(jiàn)《RAC(ReactiveCocoa) 初探》。下面要介紹的 RxSwift 就是利用的 FRP 思想。如果有 Swift 語(yǔ)法不熟悉的可以先補(bǔ)習(xí)一下 Swift 語(yǔ)法,我就惡補(bǔ)了一下 Swift 的閉包語(yǔ)法,并總結(jié)了一下,有需要的朋友也可以去看一下我的文章《Swift中的閉包》。
二、RxSwift
1、簡(jiǎn)介
ReactiveX(簡(jiǎn)寫:Rx)是一個(gè)可以幫助我們簡(jiǎn)化異步編程的框架。而 RxSwift 是 Rx 的 Swift 版本。除了 RxSwift,還有 RxJava、RxJS、Rx.Net 等,對(duì)應(yīng)的OC 版本則是 RAC(ReactiveCocoa),這里是 RxSwift 的 github 地址 ,已經(jīng)有了將近 17000 顆星了。
RxSwift 的特點(diǎn):
- 復(fù)合 - Rx 就是復(fù)合的代名詞
- 復(fù)用 - 因?yàn)樗讖?fù)合
- 清晰 - 因?yàn)槁暶鞫际遣豢勺兏?/li>
- 易用 - 因?yàn)樗橄蟮牧水惒骄幊蹋刮覀兘y(tǒng)一了代碼風(fēng)格
- 穩(wěn)定 - 因?yàn)?Rx 是完全通過(guò)單元測(cè)試的
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
在項(xiàng)目中用到的地方引入即可
import RxSwift
import RxCocoa
3、RxSwift 的常用方式
現(xiàn)在我們通過(guò)了解幾個(gè) RxSwift 的常用方式,來(lái)了解一下它的強(qiáng)大之處吧!
(1) 按鈕點(diǎn)擊事件
傳統(tǒng)實(shí)現(xiàn)方法:
button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
func buttonTapped() {
print("button Tapped")
}
Rx 實(shí)現(xiàn):
button.rx.tap
.subscribe(onNext: {
print("button Tapped")
})
.disposed(by: disposeBag)
- 你不需要使用 Target Action,這樣使得代碼邏輯清晰可見(jiàn)。
(2) 代理
這里我們以 UIScrollViewDelegate 的偏移量代理方法為例,
傳統(tǒng)實(shí)現(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 實(shí)現(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)實(shí)現(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 實(shí)現(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 定時(shí)器
Rx 實(shí)現(xiàn):
func setupTimer() {
timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
timer.subscribe(onNext: { (num) in
print(num)
})
.disposed(by: disposeBag)
}
(5) 手勢(shì)
Rx 實(shí)現(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 實(shí)現(xiàn)方式,是不是覺(jué)得特別方便快捷。了解了用法,我們?cè)賮?lái)深入了解一下 RxSwift 的核心吧。
4、RxSwift 的核心
Observable 是一個(gè)可監(jiān)聽(tīng)的 Sequence(序列)。分為有窮序列和無(wú)窮序列,主要就是用來(lái)形成一條數(shù)據(jù)流。它有三種事件:next、completed 和 error。
- next 事件主要是當(dāng) Observable 里出現(xiàn)新的數(shù)據(jù)時(shí)會(huì)發(fā)出的事件,同時(shí)該事件會(huì)攜帶新的數(shù)據(jù)對(duì)象。
- completed 事件是當(dāng) Observable 不再有新的數(shù)據(jù)出現(xiàn),Observable被標(biāo)記完成,并且將數(shù)據(jù)流終結(jié)。
- error 事件是指當(dāng)數(shù)據(jù)流遇到了錯(cuò)誤會(huì)發(fā)出的事件,該事件也會(huì)導(dǎo)致 Observable 被終結(jié)。
下面是一個(gè)代碼實(shí)現(xiàn)的整個(gè)流程:
// 1:創(chuàng)建序列
// AnonymousObservable -> producer.subscriber -> run
let ob = Observable<Any>.create { (obserber) -> Disposable in
// 3:發(fā)送信號(hào)
obserber.onNext("發(fā)送信號(hào)")
obserber.onCompleted()
return Disposables.create()
}
// 2:訂閱信號(hào)
let _ = ob.subscribe(onNext: { (text) in
print("訂閱到:\(text)")
}, onError: { (error) in
print("錯(cuò)誤: \(error)")
}, onCompleted: {
print("完成")
}) {
print("銷毀")
}
到此我們只是先對(duì) RxSwift 進(jìn)行了一次簡(jiǎn)單的初探,了解了它的強(qiáng)大之處和簡(jiǎn)單的用法,以及它的核心原理。后面我還會(huì)更深一步去學(xué)習(xí)使用 RxSwift!
以上的總結(jié)參考了并部分摘抄了以下文章,非常感謝以下作者的分享?。?br>
1、《RxSwift 中文文檔》
2、作者Philm_iOS的《函數(shù)響應(yīng)式編程》
3、作者我只不過(guò)是出來(lái)寫寫代碼的《RAC(ReactiveCocoa)介紹(一)——基本介紹》
4、turtleeeee的《RxSwift的學(xué)習(xí)之路(一)——Observable》
轉(zhuǎn)載請(qǐng)備注原文出處,不得用于商業(yè)傳播——凡幾多