函數(shù)響應(yīng)式編程(FRP)框架--ReactiveCocoa

? ? ? ? 身為RAC的小白表谊,希望可以和大家討論一下關(guān)于ReactiveCocoa,這個(gè)采用函數(shù)響應(yīng)式編程(FRP)的框架,以下會(huì)對(duì)ReactiveCocoa簡(jiǎn)稱為RAC。

? ? ? ? 之前看過一遍文章,說的是作為一個(gè)iOS開發(fā)者昂验,寫的每一行代碼幾乎都是在相應(yīng)某個(gè)事件缘滥,例如按鈕的點(diǎn)擊,收到網(wǎng)絡(luò)消息惩坑,屬性的變化(通過KVO)或者用戶位置的變化(通過CoreLocation)掉盅。但是這些事件都用不同的方式來處理,比如action以舒、delegate趾痘、KVO、callback等蔓钟。我很贊同這種說法永票,于是,即然這樣的話,那我們?yōu)槭裁床话堰@些需要響應(yīng)的事件流統(tǒng)一放在一起呢瓦侮。很幸運(yùn)的是艰赞,Github有一個(gè)開源項(xiàng)目,即ReactiveCocoa簡(jiǎn)稱RAC肚吏,就是基于響應(yīng)式編程思想的Objective-C實(shí)踐方妖。

? ? ? ? ? 那么何為RAC呢?

? ? ? ? ?RAC是為應(yīng)用中發(fā)生的不同事件流提供了一個(gè)標(biāo)準(zhǔn)接口罚攀,我們可以使用一些基本工具來更容易的連接党觅、過濾和組合。


RAC結(jié)合了幾種編程風(fēng)格:

? ? ? ?函數(shù)式編程(Functional Programming):使用高階函數(shù)斋泄,例如函數(shù)用其他函數(shù)作為參數(shù)杯瞻。

? ? ? ?那么什么是函數(shù)式編程呢??

? ? ? ? 簡(jiǎn)單的一句話說炫掐,『盡量將操作都寫在一起魁莉,也就是寫成一個(gè)嵌套的函數(shù)』這就是函數(shù)式編程的核心思想,代表性項(xiàng)目 AFN

而它的本質(zhì)就是募胃,往方法里面?zhèn)魅隻lock , 方法里面在嵌套block.

? ? ? ? ? 響應(yīng)式編程(Reactive Programming):關(guān)注于數(shù)據(jù)流和變化傳播旗唁。

? ? ? ? ? 其實(shí)大家都接觸過響應(yīng)式編程,就是所謂的KVO痹束。

? ? ? ? ? KVO 大家肯定都接觸過吧检疫?一個(gè)屬性的改變立刻做出反應(yīng),我不管你的屬性有沒有值祷嘶,我不管你的屬性來了沒有屎媳,我就是監(jiān)聽,只要你一來我就做出響應(yīng)论巍,其實(shí)KVO的本質(zhì)就是烛谊,監(jiān)聽一個(gè)對(duì)象,他有沒有監(jiān)聽set方法嘉汰。然后將set方法重寫晒来。RAC 就是典型的響應(yīng)式編程,我信號(hào)發(fā)出去之后訂閱者就是負(fù)責(zé)監(jiān)聽郑现,不管你來不來,不管你有沒有荧降,反正我就是監(jiān)聽著接箫,只要你一來我就做出反應(yīng)。

? ? ? ? ?所以朵诫,你可能聽說過ReactiveCocoa被描述為函數(shù)響應(yīng)式編程(FRP)框架辛友。

? ? ? ? 有句比喻很好很形象的對(duì)RAC做了總結(jié):“可以把信號(hào)想象成水龍頭,只不過里面不是水,而是玻璃球(value)废累,直徑跟水管的內(nèi)徑一樣邓梅,這樣就能保證玻璃球是依次排列,不會(huì)出現(xiàn)并排的情況(數(shù)據(jù)都是線性處理的邑滨,不會(huì)出現(xiàn)并發(fā)情況)日缨。水龍頭的開關(guān)默認(rèn)是關(guān)的,除非有了接收方(subscriber)掖看,才會(huì)打開匣距。這樣只要有新的玻璃球進(jìn)來,就會(huì)自動(dòng)傳送給接收方哎壳∫愦可以在水龍頭上加一個(gè)過濾嘴(filter),不符合的不讓通過归榕,也可以加一個(gè)改動(dòng)裝置尸红,把球改變成符合自己的需求(map)。也可以把多個(gè)水龍頭合并成一個(gè)新的水龍頭(combineLatest:reduce:)刹泄,這樣只要其中的一個(gè)水龍頭有玻璃球出來外里,這個(gè)新合并的水龍頭就會(huì)得到這個(gè)球⊙”--? 來自博文http://blog.csdn.net/xdrt81y/article/details/30624469

首先導(dǎo)入RAC框架:

可以通過CocoaPods導(dǎo)入RAC框架:(注意RAC的版本)

導(dǎo)入? pod 'ReactiveCocoa', '~> 2.4.0' ?&& ?use_frameworks! #導(dǎo)入才不會(huì)報(bào)錯(cuò)?

或者? 導(dǎo)入pod 'ReactiveObjC', '~> 3.0.0'

? ? ? ? ReactiveCocoa 2.5以后引入Swift级乐,所以我們?cè)贠C開發(fā)中需要配入之前的版本,否則會(huì)錯(cuò)的一發(fā)不可收拾哦O亟场7缈啤!F虻贼穆!

? ? ? ? RAC為應(yīng)用中發(fā)生的不同事件流提供了一個(gè)標(biāo)準(zhǔn)接口。在ReactiveCocoa術(shù)語中這個(gè)叫做信號(hào)(signal)兰粉,由RACSignal類表示故痊。

? ? ? ? ReactiveCocoa signal(RACSignal)發(fā)送事件流給它的subscriber(訂閱者)。目前總共有三種類型的事件:next玖姑、error愕秫、completed。一個(gè)signal在因error終止或者完成前焰络,可以發(fā)送任意數(shù)量的next事件戴甩。RACSignal有很多方法可以來訂閱不同的事件類型。每個(gè)方法都需要至少一個(gè)block闪彼,當(dāng)事件發(fā)生時(shí)就會(huì)執(zhí)行block中的邏輯甜孤。


那么下面來一下實(shí)戰(zhàn)操作吧!!=纱ā\猿怼!


一把夸、創(chuàng)建信號(hào)

? ? ? ? 使用RACSignal的createSignal:方法來創(chuàng)建信號(hào)而线。方法的參數(shù)是一個(gè)block,這個(gè)block描述了這個(gè)信號(hào)扎即。當(dāng)這個(gè)信號(hào)有subscriber時(shí)吞获,block里的代碼就會(huì)執(zhí)行。

? ? ? ?block的參數(shù)是一個(gè)subscriber實(shí)例谚鄙,它遵循RACSubscriber協(xié)議各拷,協(xié)議里有一些方法來產(chǎn)生事件,你可以發(fā)送任意數(shù)量的next事件闷营,或者用error\complete事件來終止烤黍。本例中,信號(hào)發(fā)送了一個(gè)next事件來表示登錄是否成功傻盟,隨后是一個(gè)complete事件速蕊。

? ? ? 這個(gè)block的返回值是一個(gè)RACDisposable對(duì)象,它允許你在一個(gè)訂閱被取消時(shí)執(zhí)行一些清理工作娘赴。當(dāng)前的信號(hào)不需要執(zhí)行清理操作规哲,所以返回nil就可以了。

? ? ? ? - (RACSignal*)signInSignal {

? ? ? ? ? ? ? ?return[RACSignalcreateSignal:^RACDisposable*(idsubscriber){

? ? ? [self.signInService ? signInWithUsername:self.usernameTextField.text password:self.passwordTextField.text

complete:^(BOOLsuccess){

? ? ? ? ?[subscribersendNext:@(success)];

? ? ? ? ? [subscribersendCompleted];

? ? ? ? ?}];

? ? ? ? ?returnnil;

? ? ?}];

}

二诽表、使用RAC宏

? ? ? ?RAC宏允許直接把信號(hào)的輸出應(yīng)用到對(duì)象的屬性上唉锌。RAC宏有兩個(gè)參數(shù),第一個(gè)是需要設(shè)置屬性值的對(duì)象竿奏,第二個(gè)是屬性名袄简。每次信號(hào)產(chǎn)生一個(gè)next事件,傳遞過來的值都會(huì)應(yīng)用到該屬性上泛啸。

? ? ? ? RAC(self.passwordTextField.backgroundColor) = [validPassword Signalmap:^id(NSNumber*passwordValid) {

? ? ? ? ? ? ? ? NSLog(@"%d",[passwordValidboolValue]);

? ? ? ?return[passwordValid boolValue]?[UIColor clearColor]:[UIColor yellowColor];

? ? ? ?}];

? ? ? ?RAC(self.usernameTextField.backgroundColor) = [validUsername Signalmap:^id(NSNumber*usernameValid) {

? ? ? ? ? ? ? ? ? NSLog(@"%d",[usernameValid boolValue]);

? ? ? ?return[usernameValid boolValue]?[UIColor clearColor]:[UIColor yellowColor];

? ? ?}];


三绿语、信號(hào)聚合

? ? ? ?使用combineLatest:reduce:方法把幾個(gè)信號(hào)RACSignal產(chǎn)生的最新的值聚合在一起,并生成一個(gè)新的信號(hào)候址。每次這兩個(gè)源信號(hào)的任何一個(gè)產(chǎn)生新值時(shí)吕粹,reduce block都會(huì)執(zhí)行,block的返回值會(huì)發(fā)給下一個(gè)信號(hào)岗仑。

? ? ? ? ? ? RACSignal *signUpActiveSignal = [RACSignalcombineLatest:@[validUsernameSignal,validPasswordSignal] ? ? ? ?reduce:^id(NSNumber*usernameValid,NSNumber*passwordValid){

? ? ? ? ? ? ?return@([usernameValidboolValue]&&[passwordValid boolValue]);

? ? ? ? ? ? }];

? ? ? ? ? ? [signUpActiveSignal subscribeNext:^(NSNumber*signupActive) {

? ? ? ? ? ? self.signInButton.enabled= [signupActive boolValue];

}];


ReactiveCocoa的核心就是信號(hào)匹耕,而它不過就是事件流,ReactiveCocoa的主旨是讓你的代碼更簡(jiǎn)潔易懂!赔蒲!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子舞虱,更是在濱河造成了極大的恐慌欢际,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件矾兜,死亡現(xiàn)場(chǎng)離奇詭異损趋,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)椅寺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門浑槽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人返帕,你說我怎么就攤上這事桐玻。” “怎么了荆萤?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵镊靴,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我链韭,道長(zhǎng)偏竟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任敞峭,我火速辦了婚禮踊谋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘旋讹。我一直安慰自己殖蚕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布骗村。 她就那樣靜靜地躺著嫌褪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪胚股。 梳的紋絲不亂的頭發(fā)上笼痛,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音琅拌,去河邊找鬼缨伊。 笑死,一個(gè)胖子當(dāng)著我的面吹牛进宝,可吹牛的內(nèi)容都是我干的刻坊。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼党晋,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼谭胚!你這毒婦竟也來了徐块?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤灾而,失蹤者是張志新(化名)和其女友劉穎胡控,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體旁趟,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡昼激,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了锡搜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片橙困。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖耕餐,靈堂內(nèi)的尸體忽然破棺而出凡傅,到底是詐尸還是另有隱情,我是刑警寧澤蛾方,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布像捶,位于F島的核電站,受9級(jí)特大地震影響桩砰,放射性物質(zhì)發(fā)生泄漏拓春。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一亚隅、第九天 我趴在偏房一處隱蔽的房頂上張望硼莽。 院中可真熱鬧,春花似錦煮纵、人聲如沸懂鸵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽匆光。三九已至,卻和暖如春酿联,著一層夾襖步出監(jiān)牢的瞬間终息,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工贞让, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留周崭,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓喳张,卻偏偏與公主長(zhǎng)得像续镇,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子销部,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容