1.ReactiveCocoa簡介
ReactiveCocoa(簡稱為RAC
),是由Github
開源的一個應用于iOS和OS開發的新框架,Cocoa是蘋果整套框架的簡稱,因此很多蘋果框架喜歡以Cocoa結尾。
2.ReactiveCocoa作用
- 在我們iOS開發過程中,當某些事件響應的時候,需要處理某些業務邏輯,這些事件都用不同的方式來處理。
- 比如按鈕的點擊使用action,ScrollView滾動使用delegate,屬性值改變使用KVO等系統提供的方式。
- 其實這些事件,都可以通過RAC處理
- ReactiveCocoa為事件提供了很多處理方法,而且利用RAC處理事件很方便,可以把要處理的事情,和監聽的事情的代碼放在一起,這樣非常方便我們管理,就不需要跳到對應的方法里。非常符合我們開發中
高聚合,低耦合
的思想。
3.編程思想
在開發中我們也不能太依賴于某個框架,否則這個框架不更新了,導致項目后期沒辦法維護,比如之前Facebook提供的Three20框架
,在當時也是神器,但是后來不更新了,也就沒什么人用了。因此我感覺學習一個框架,還是有必要了解它的編程思想
。
編程思想的由來
:在開發中我們會遇見各種各樣的需求,經常會思考如何快速的完成這些需求,這樣就會慢慢形成快速完成這些需求的思想。
先簡單介紹下目前咱們已知的編程思想
。
3.1 面向過程
:處理事情以過程為核心,一步一步的實現。
3.2 面向對象
:萬物皆對象
3.3 鏈式編程思想
:是將多個操作(多行代碼)通過點號(.)鏈接在一起成為一句代碼,使代碼可讀性好。a(1).b(2).c(3)
-
鏈式編程特點
:方法的返回值是block,block必須有返回值(本身對象),block參數(需要操作的值) -
代表
:masonry框架。
3.4 響應式編程思想
:不需要考慮調用順序,只需要知道考慮結果,類似于蝴蝶效應,產生一個事件,會影響很多東西,這些事件像流一樣的傳播出去,然后影響結果,借用面向對象的一句話,萬物皆是流。
-
代表
:KVO運用。
3.5 函數式編程思想
:是把操作盡量寫成一系列嵌套的函數或者方法調用。
函數式編程本質
:就是往方法中傳入Block,方法中嵌套Block調用,把代碼聚合起來管理函數式編程特點
:每個方法必須有返回值(本身對象),把函數或者Block當做參數,block參數(需要操作的值)block返回值(操作結果)代表
:ReactiveCocoa。
4.ReactiveCocoa編程思想
ReactiveCocoa結合了幾種編程風格:
函數式編程(Functional Programming)
響應式編程(Reactive Programming)
所以,你可能聽說過ReactiveCocoa被描述為函數響應式編程(FRP)框架。
以后使用RAC解決問題,就不需要考慮調用順序,直接考慮結果,把每一次操作都寫成一系列嵌套的方法中,使代碼高聚合,方便管理。
5.如何導入ReactiveCocoa框架
通常都會使用CocoaPods(用于管理第三方框架的插件)幫助我們導入。
PS:CocoaPods教程(http://code4app.com/article/cocoapods-install-usage)
注意
:
這里有一點要注意下就是RAC的版本問題,由于還沒學習Swift,所以我是用OC編寫程序的,最新版的RAC已經支持Swift了,但是在OC的程序安裝最新版的RAC可能跑不起來,所以推薦大家使用2.5版本以下的RAC
6.ReactiveCocoa常見類。
學習框架首要之處:個人認為先要搞清楚框架中常用的類,在RAC中最核心的類RACSiganl,搞定這個類就能用ReactiveCocoa開發了。
RACSiganl
:信號類,一般表示將來有數據傳遞,只要有數據改變,信號內部接收到數據,就會馬上發出數據。
信號類(RACSiganl),只是表示當數據改變時,信號內部會發出數據,它本身不具備發送信號的能力,而是交給內部一個訂閱者去發出。
默認一個信號都是冷信號,也就是值改變了,也不會觸發,只有訂閱了這個信號,這個信號才會變為熱信號,值改變了才會觸發。
如何訂閱信號:調用信號RACSignal的subscribeNext就能訂閱。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// RACSignal:有數據產生的時候,就使用RACSignal
// RACSignal使用三部曲: 1.創建信號 2.訂閱信號 3.發送信號
// 便于理解,我們先拆分block
// RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// return nil;
// }];
// 拆分后的block
RACDisposable *(^didSubscribe)(id<RACSubscriber> subscriber) = ^RACDisposable *(id<RACSubscriber> subscriber) {
// didSubscribe調用:只要一個信號被訂閱就會調用
// didSubscribe作用:發送數據
NSLog(@"信號被訂閱");
// 3.發送數據
[subscriber sendNext:@1];
return nil;
};
// 1.創建信號(冷信號)
RACSignal *signal = [RACSignal createSignal:didSubscribe];
// 2.訂閱信號(熱信號)
[signal subscribeNext:^(id x) {
// nextBlock調用:只要訂閱者發送數據就會調用
// nextBlock作用:處理數據,展示到UI上面
// x:信號發送的內容
NSLog(@"%@",x);
}];
'請跳入方法里面看'
// 只要訂閱者調用sendNext,就會執行nextBlock
// 只要訂閱RACDynamicSignal,就會執行didSubscribe
// 前提條件是RACDynamicSignal,不同類型信號的訂閱,處理訂閱的事情不一樣
// RACSignal底層實現:
// 1.創建信號,首先把didSubscribe保存到信號中,還不會觸發。
// 2.當信號被訂閱,也就是調用signal的subscribeNext:nextBlock
// 2.2 subscribeNext內部會創建訂閱者subscriber,并且把nextBlock保存到subscriber中。
// 2.1 subscribeNext內部會調用siganl的didSubscribe
// 3.siganl的didSubscribe中調用[subscriber sendNext:@1];
// 3.1 sendNext底層其實就是執行subscriber的nextBlock
// 1.創建信號
RACSignal *siganl = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// block調用時刻:每當有訂閱者訂閱信號,就會調用block。
// 2.發送信號
[subscriber sendNext:@1];
// 如果不在發送數據,最好發送信號完成,內部會自動調用[RACDisposable disposable]取消訂閱信號。
[subscriber sendCompleted];
return [RACDisposable disposableWithBlock:^{
// block調用時刻:當信號發送完成或者發送錯誤,就會自動執行這個block,取消訂閱信號。
// 執行完Block后,當前信號就不在被訂閱了。
NSLog(@"信號被銷毀");
}];
}];
// 3.訂閱信號,才會激活信號.
[siganl subscribeNext:^(id x) {
// block調用時刻:每當有信號發出數據,就會調用block.
NSLog(@"接收到數據:%@",x);
}];