1.ReactiveCocoa簡介
ReactiveCocoa(簡稱為RAC
),是由Github
開源的一個應(yīng)用于iOS和OS開發(fā)的新框架,Cocoa是蘋果整套框架的簡稱讨勤,因此很多蘋果框架喜歡以Cocoa結(jié)尾阳啥。
2.ReactiveCocoa作用
- 在我們iOS開發(fā)過程中,當(dāng)某些事件響應(yīng)的時候绸吸,需要處理某些業(yè)務(wù)邏輯,這些事件都用不同的方式來處理。
- 比如按鈕的點擊使用action侈贷,ScrollView滾動使用delegate毕泌,屬性值改變使用KVO等系統(tǒng)提供的方式。
- 其實這些事件纯趋,都可以通過RAC處理
- ReactiveCocoa為事件提供了很多處理方法憎兽,而且利用RAC處理事件很方便冷离,可以把要處理的事情,和監(jiān)聽的事情的代碼放在一起纯命,這樣非常方便我們管理西剥,就不需要跳到對應(yīng)的方法里。非常符合我們開發(fā)中
高聚合亿汞,低耦合
的思想瞭空。
3.編程思想
在開發(fā)中我們也不能太依賴于某個框架,否則這個框架不更新了疗我,導(dǎo)致項目后期沒辦法維護咆畏,比如之前Facebook提供的Three20框架
,在當(dāng)時也是神器碍粥,但是后來不更新了鳖眼,也就沒什么人用了。因此我感覺學(xué)習(xí)一個框架嚼摩,還是有必要了解它的編程思想
钦讳。
編程思想的由來
:在開發(fā)中我們會遇見各種各樣的需求,經(jīng)常會思考如何快速的完成這些需求枕面,這樣就會慢慢形成快速完成這些需求的思想愿卒。
先簡單介紹下目前咱們已知的編程思想
。
3.1 面向過程
:處理事情以過程為核心潮秘,一步一步的實現(xiàn)琼开。
3.2 面向?qū)ο?/code>:萬物皆對象
3.3 鏈?zhǔn)骄幊趟枷?/code>:是將多個操作(多行代碼)通過點號(.)鏈接在一起成為一句代碼,使代碼可讀性好。a(1).b(2).c(3)
-
鏈?zhǔn)骄幊烫攸c
:方法的返回值是block,block必須有返回值(本身對象)枕荞,block參數(shù)(需要操作的值) -
代表
:masonry框架柜候。
3.4 響應(yīng)式編程思想
:不需要考慮調(diào)用順序,只需要知道考慮結(jié)果躏精,類似于蝴蝶效應(yīng)渣刷,產(chǎn)生一個事件,會影響很多東西矗烛,這些事件像流一樣的傳播出去辅柴,然后影響結(jié)果,借用面向?qū)ο蟮囊痪湓挷t吃,萬物皆是流碌嘀。
-
代表
:KVO運用。
3.5 函數(shù)式編程思想
:是把操作盡量寫成一系列嵌套的函數(shù)或者方法調(diào)用歪架。
函數(shù)式編程本質(zhì)
:就是往方法中傳入Block,方法中嵌套Block調(diào)用股冗,把代碼聚合起來管理函數(shù)式編程特點
:每個方法必須有返回值(本身對象),把函數(shù)或者Block當(dāng)做參數(shù),block參數(shù)(需要操作的值)block返回值(操作結(jié)果)代表
:ReactiveCocoa。
4.ReactiveCocoa編程思想
ReactiveCocoa結(jié)合了幾種編程風(fēng)格:
函數(shù)式編程(Functional Programming)
響應(yīng)式編程(Reactive Programming)
所以牡拇,你可能聽說過ReactiveCocoa被描述為函數(shù)響應(yīng)式編程(FRP)框架魁瞪。
以后使用RAC解決問題穆律,就不需要考慮調(diào)用順序,直接考慮結(jié)果导俘,把每一次操作都寫成一系列嵌套的方法中峦耘,使代碼高聚合,方便管理旅薄。
5.如何導(dǎo)入ReactiveCocoa框架
通常都會使用CocoaPods(用于管理第三方框架的插件)幫助我們導(dǎo)入辅髓。
PS:CocoaPods教程(http://code4app.com/article/cocoapods-install-usage)
注意
:
這里有一點要注意下就是RAC的版本問題,由于還沒學(xué)習(xí)Swift少梁,所以我是用OC編寫程序的洛口,最新版的RAC已經(jīng)支持Swift了,但是在OC的程序安裝最新版的RAC可能跑不起來凯沪,所以推薦大家使用2.5版本以下的RAC
6.ReactiveCocoa常見類第焰。
學(xué)習(xí)框架首要之處:個人認(rèn)為先要搞清楚框架中常用的類,在RAC中最核心的類RACSiganl,搞定這個類就能用ReactiveCocoa開發(fā)了妨马。
RACSiganl
:信號類,一般表示將來有數(shù)據(jù)傳遞挺举,只要有數(shù)據(jù)改變,信號內(nèi)部接收到數(shù)據(jù)烘跺,就會馬上發(fā)出數(shù)據(jù)湘纵。
信號類(RACSiganl),只是表示當(dāng)數(shù)據(jù)改變時滤淳,信號內(nèi)部會發(fā)出數(shù)據(jù)梧喷,它本身不具備發(fā)送信號的能力,而是交給內(nèi)部一個訂閱者去發(fā)出脖咐。
默認(rèn)一個信號都是冷信號铺敌,也就是值改變了,也不會觸發(fā)屁擅,只有訂閱了這個信號适刀,這個信號才會變?yōu)闊嵝盘枺蹈淖兞瞬艜|發(fā)煤蹭。
如何訂閱信號:調(diào)用信號RACSignal的subscribeNext就能訂閱。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// RACSignal:有數(shù)據(jù)產(chǎn)生的時候,就使用RACSignal
// RACSignal使用三部曲: 1.創(chuàng)建信號 2.訂閱信號 3.發(fā)送信號
// 便于理解,我們先拆分block
// RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// return nil;
// }];
// 拆分后的block
RACDisposable *(^didSubscribe)(id<RACSubscriber> subscriber) = ^RACDisposable *(id<RACSubscriber> subscriber) {
// didSubscribe調(diào)用:只要一個信號被訂閱就會調(diào)用
// didSubscribe作用:發(fā)送數(shù)據(jù)
NSLog(@"信號被訂閱");
// 3.發(fā)送數(shù)據(jù)
[subscriber sendNext:@1];
return nil;
};
// 1.創(chuàng)建信號(冷信號)
RACSignal *signal = [RACSignal createSignal:didSubscribe];
// 2.訂閱信號(熱信號)
[signal subscribeNext:^(id x) {
// nextBlock調(diào)用:只要訂閱者發(fā)送數(shù)據(jù)就會調(diào)用
// nextBlock作用:處理數(shù)據(jù),展示到UI上面
// x:信號發(fā)送的內(nèi)容
NSLog(@"%@",x);
}];
'請?zhí)敕椒ɡ锩婵?
// 只要訂閱者調(diào)用sendNext,就會執(zhí)行nextBlock
// 只要訂閱RACDynamicSignal,就會執(zhí)行didSubscribe
// 前提條件是RACDynamicSignal,不同類型信號的訂閱,處理訂閱的事情不一樣
// RACSignal底層實現(xiàn):
// 1.創(chuàng)建信號取视,首先把didSubscribe保存到信號中硝皂,還不會觸發(fā)。
// 2.當(dāng)信號被訂閱作谭,也就是調(diào)用signal的subscribeNext:nextBlock
// 2.2 subscribeNext內(nèi)部會創(chuàng)建訂閱者subscriber稽物,并且把nextBlock保存到subscriber中。
// 2.1 subscribeNext內(nèi)部會調(diào)用siganl的didSubscribe
// 3.siganl的didSubscribe中調(diào)用[subscriber sendNext:@1];
// 3.1 sendNext底層其實就是執(zhí)行subscriber的nextBlock
// 1.創(chuàng)建信號
RACSignal *siganl = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// block調(diào)用時刻:每當(dāng)有訂閱者訂閱信號折欠,就會調(diào)用block贝或。
// 2.發(fā)送信號
[subscriber sendNext:@1];
// 如果不在發(fā)送數(shù)據(jù)吼过,最好發(fā)送信號完成,內(nèi)部會自動調(diào)用[RACDisposable disposable]取消訂閱信號咪奖。
[subscriber sendCompleted];
return [RACDisposable disposableWithBlock:^{
// block調(diào)用時刻:當(dāng)信號發(fā)送完成或者發(fā)送錯誤盗忱,就會自動執(zhí)行這個block,取消訂閱信號。
// 執(zhí)行完Block后羊赵,當(dāng)前信號就不在被訂閱了趟佃。
NSLog(@"信號被銷毀");
}];
}];
// 3.訂閱信號,才會激活信號.
[siganl subscribeNext:^(id x) {
// block調(diào)用時刻:每當(dāng)有信號發(fā)出數(shù)據(jù),就會調(diào)用block.
NSLog(@"接收到數(shù)據(jù):%@",x);
}];