初識ReactiveCocoa

今天主要分享內(nèi)容:

  • ReactiveCocoa簡單介紹
  • 響應(yīng)式編程和函數(shù)編程的概述
  • RACSignal 信號
  • RACSignald訂閱過程
  • First Demo
  • Second Demo
  • 參考鏈接

ReactiveCocoa

  • GitHub mac 客戶端副產(chǎn)物
  • FRP(響應(yīng)式函數(shù)編程)在cocoa框架的實現(xiàn)
  • ReactiveCocoa可以對代理模式, target-action模式,鍵值對觀察(KVO)等進行替代

響應(yīng)式函數(shù)編程概述

ReactiveCocoa框架讓你可以在iOS應(yīng)用中使用響應(yīng)式函數(shù)編程(FRP)

  • 命令式編程 VS 函數(shù)式編程 VS 響應(yīng)式編程(粗淺介紹)
int func(int x) 
{
  int result = 1;
  for (int i = 1; i <=x; ++i) 
  {
    result *= i;
  }
} ```
命令式編程關(guān)心解決問題的步驟
你得把達到目的的步驟詳細的描述出來群叶,
然后交給機器去運行茂嗓。
需要管理非常多的中間狀態(tài)量刁赦,代碼繁雜嘹屯。

int func(int x)
{
if (x == 1) return 1;
return x * func(x - 1);
} ```
函數(shù)式編程關(guān)心數(shù)據(jù)的映射
這里的映射就是數(shù)學(xué)上「函數(shù)」的概念,
一種東西和另一種東西之間的對應(yīng)關(guān)系评肆。
沒有狀態(tài)量慢蜓,簡潔高效亿絮。

void test() {
 int a = 5;
 int b = 6;
 int c = a + b;
 int d = funAdd(&a , &b);//a b中的值
 a = 10;
 NSLog(@"%d",c);
} ```
響應(yīng)式編程是一種面向數(shù)據(jù)流和變化傳播的編程范式岭粤。
在響應(yīng)式編程中d的值會隨著a或b的更新而更新惜索。


### RACSignal 信號

ReactiveCocoa四大核心組件構(gòu)成:
信號源:RACStream 及其子類;
訂閱者:RACSubscriber 的實現(xiàn)類及其子類绍在;
調(diào)度器:RACScheduler 及其子類门扇;
清潔工:RACDisposable 及其子類。

其中偿渡,信號源又是最核心的部分,其他組件都是圍繞它運作的霸奕。
ReactiveCocoa使用信號來代表異步事件溜宽,提供了一種統(tǒng)一的方式來處理所有異步的行為,包括代理方法质帅、block 回調(diào)适揉、target-action 機制、通知煤惩、KVO 等:

// 代理方法
[[self
rac_signalForSelector:@selector(webViewDidStartLoad:)
fromProtocol:@protocol(UIWebViewDelegate)]
subscribeNext:^(id x) {
// 實現(xiàn) webViewDidStartLoad: 代理方法
}];

// target-action
[[self.avatarButton
rac_signalForControlEvents:UIControlEventTouchUpInside]
subscribeNext:^(UIButton *avatarButton) {
// avatarButton 被點擊了
}];

// 通知
[[[NSNotificationCenter defaultCenter]
rac_addObserverForName:kReachabilityChangedNotification object:nil]
subscribeNext:^(NSNotification *notification) {
// 收到 kReachabilityChangedNotification 通知
}];

// KVO
[RACObserve(self, username) subscribeNext:^(NSString *username) {
// 用戶名發(fā)生了變化
}];

### RACSignald訂閱過程
// 創(chuàng)建信號 并發(fā)送信號
//使用RACSignal的createSignal:方法創(chuàng)建信號嫉嘀。描述這個信號的block是這個方法唯一的入?yún)ⅰ.斶@個信號有訂閱者的時候魄揉,block中的代碼就會執(zhí)行剪侮。

RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    [subscriber sendNext:@1];
    [subscriber sendNext:@2];
    [subscriber sendCompleted];
    return [RACDisposable disposableWithBlock:^{
        NSLog(@"dispose");
    }];
}];
// 訂閱信號
RACDisposable *disposable = [signal subscribeNext:^(id x) {
    NSLog(@"next value is %@",x); 
} error:^(NSError *error) {
    NSLog(@"error -> %@",[error description]);
} completed:^{
    NSLog(@"It finished success");
}];
[disposable dispose];

//ReactiveCocoa的信號(表現(xiàn)為RACSignal類)會向他的訂閱者們發(fā)送事件流。
//發(fā)送的事件分為三種類型:next洛退,error 和 completed瓣俯。
//一個信號在因為報錯或完成的終止前可以發(fā)送若干個事件。


### First Demo
實現(xiàn)一個登陸界面

![](http://upload-images.jianshu.io/upload_images/1292402-4ff2c2884df27598.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

要求:
1. User & Password不少于3位
2. 低于3位顯示紅色兵怯,正常顯示藍色
3. 登錄按鈕只有在用戶名和密碼都有效輸入時才能使用

Answer 1

//ReactiveCocoa框架使用category為很多標準的UIKit控件添加了信號
//可以對它們的各種事件進行訂閱

//1.創(chuàng)建信號
RACSignal *userName = [self.usernameTextField rac_textSignal];
//2.篩選
RACSignal *validUsername = [userName filter:^BOOL(id value) {
NSString *text = value;
return [self isValidUsername:text];
}];
//3.調(diào)用信號RACSignal的subscribeNext就能訂閱,
//subscribeNext:方法就提供了一個block彩匕,
//在每個next事件到達時執(zhí)行里面的代碼。
[validUsername subscribeNext:^(id x) {
NSLog(@"%@",x);
}];

Answer 2

[[self.usernameTextField.rac_textSignal
map:^id(NSString *username) {
return [self isValidUsername:username] ? [UIColor whiteColor] : [UIColor redColor];
}]
subscribeNext:^(UIColor *color) {
self.usernameTextField.backgroundColor = color;
}];

[[self.passworkTextField.rac_textSignal
map:^id(NSString *password) {
return [self isValidUsername:password] ? [UIColor whiteColor] : [UIColor redColor];
}]
subscribeNext:^(UIColor *color) {
self.passworkTextField.backgroundColor = color;
}];```
Answer 3

//創(chuàng)建兩個發(fā)送布爾值的信號validUsernameSignal媒区、validPasswordSignal
  //對用戶名和密碼的輸入進行驗證驼仪。
  RACSignal *validUsernameSignal =
  [self.usernameTextField.rac_textSignal
   map:^id(NSString *text) {
     return @([self isValidUsername:text]);
   }];
  
  RACSignal *validPasswordSignal =
  [self.passworkTextField.rac_textSignal
   map:^id(NSString *text) {
     return @([self isValidPassword:text]);
   }];
  //信號合成
  //接下來的任務(wù)就是合成這兩個信號掸犬,用以共同決定登錄按鈕是否可用
  RACSignal *signUpActiveSignal =
  [RACSignal combineLatest:@[validUsernameSignal, validPasswordSignal]
                    reduce:^id(NSNumber *usernameValid, NSNumber *passwordValid) {
                      return @([usernameValid boolValue] && [passwordValid boolValue]);
                    }];
  //上面的代碼使用combineLatest:reduce:方法   (RACSignal合成方法可以合成任意數(shù)量的信號)
  //獲取validUsernameSignal和validPasswordSignal的最近一個信號值并組合成一個全新的信號。
  //每當兩個源信號的其中一個發(fā)送新值绪爸,
  //reduce里的block代碼塊就會執(zhí)行(reduce中 block的入?yún)⒑驮葱盘栆灰粚?yīng))
  //其返回的值會作為合成信號的值發(fā)送出去湾碎。
  
  //最后是訂閱
  [signUpActiveSignal subscribeNext:^(NSNumber *signupActive) {
    self.signinBnt.enabled = [signupActive boolValue];
  }];

Second Demo

1.主動獲取數(shù)據(jù)并刷新TableView
2.根據(jù)搜索關(guān)鍵字獲取指定數(shù)據(jù),并刷新TableView毡泻;

Demo地址

參考鏈接

Reactive github
美團的幾篇博客
RACSignal的Subscription深入分析
raywenderlich 上的文章:
http://www.raywenderlich.com/62699/reactivecocoa-tutorial-pt1胜茧、http://www.raywenderlich.com/62796/reactivecocoa-tutorial-pt2http://www.raywenderlich.com/74106/mvvm-tutorial-with-reactivecocoa-part-1仇味、http://www.raywenderlich.com/74131/mvvm-tutorial-with-reactivecocoa-part-2呻顽。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市丹墨,隨后出現(xiàn)的幾起案子廊遍,更是在濱河造成了極大的恐慌,老刑警劉巖贩挣,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件喉前,死亡現(xiàn)場離奇詭異,居然都是意外死亡王财,警方通過查閱死者的電腦和手機卵迂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绒净,“玉大人见咒,你說我怎么就攤上這事」医” “怎么了改览?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長缤言。 經(jīng)常有香客問我宝当,道長,這世上最難降的妖魔是什么胆萧? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任庆揩,我火速辦了婚禮,結(jié)果婚禮上鸳碧,老公的妹妹穿的比我還像新娘盾鳞。我一直安慰自己,他們只是感情好瞻离,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布腾仅。 她就那樣靜靜地躺著,像睡著了一般套利。 火紅的嫁衣襯著肌膚如雪推励。 梳的紋絲不亂的頭發(fā)上鹤耍,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機與錄音验辞,去河邊找鬼稿黄。 笑死,一個胖子當著我的面吹牛跌造,可吹牛的內(nèi)容都是我干的杆怕。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼壳贪,長吁一口氣:“原來是場噩夢啊……” “哼陵珍!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起违施,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤互纯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后磕蒲,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體留潦,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年辣往,在試婚紗的時候發(fā)現(xiàn)自己被綠了兔院。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡站削,死狀恐怖秆乳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情钻哩,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布肛冶,位于F島的核電站街氢,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏睦袖。R本人自食惡果不足惜珊肃,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望馅笙。 院中可真熱鬧伦乔,春花似錦、人聲如沸董习。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽皿淋。三九已至招刹,卻和暖如春恬试,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背疯暑。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工训柴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人妇拯。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓幻馁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親越锈。 傳聞我的和親對象是個殘疾皇子仗嗦,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

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