初識(shí)ReactiveCocoa

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

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

ReactiveCocoa

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

響應(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)心解決問(wèn)題的步驟
你得把達(dá)到目的的步驟詳細(xì)的描述出來(lái),
然后交給機(jī)器去運(yù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ù)」的概念,
一種東西和另一種東西之間的對(duì)應(yīng)關(guān)系。
沒(méi)有狀態(tài)量,簡(jiǎn)潔高效。

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的值會(huì)隨著a或b的更新而更新。


### RACSignal 信號(hào)

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

其中,信號(hào)源又是最核心的部分,其他組件都是圍繞它運(yùn)作的。
ReactiveCocoa使用信號(hào)來(lái)代表異步事件,提供了一種統(tǒng)一的方式來(lái)處理所有異步的行為,包括代理方法、block 回調(diào)、target-action 機(jī)制、通知、KVO 等:

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

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

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

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

### RACSignald訂閱過(guò)程
// 創(chuàng)建信號(hào) 并發(fā)送信號(hào)
//使用RACSignal的createSignal:方法創(chuàng)建信號(hào)。描述這個(gè)信號(hào)的block是這個(gè)方法唯一的入?yún)?。?dāng)這個(gè)信號(hào)有訂閱者的時(shí)候,block中的代碼就會(huì)執(zhí)行。

RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    [subscriber sendNext:@1];
    [subscriber sendNext:@2];
    [subscriber sendCompleted];
    return [RACDisposable disposableWithBlock:^{
        NSLog(@"dispose");
    }];
}];
// 訂閱信號(hào)
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的信號(hào)(表現(xiàn)為RACSignal類)會(huì)向他的訂閱者們發(fā)送事件流。
//發(fā)送的事件分為三種類型:next,error 和 completed。
//一個(gè)信號(hào)在因?yàn)閳?bào)錯(cuò)或完成的終止前可以發(fā)送若干個(gè)事件。


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

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

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

Answer 1

//ReactiveCocoa框架使用category為很多標(biāo)準(zhǔn)的UIKit控件添加了信號(hào)
//可以對(duì)它們的各種事件進(jìn)行訂閱

//1.創(chuàng)建信號(hào)
RACSignal *userName = [self.usernameTextField rac_textSignal];
//2.篩選
RACSignal *validUsername = [userName filter:^BOOL(id value) {
NSString *text = value;
return [self isValidUsername:text];
}];
//3.調(diào)用信號(hào)RACSignal的subscribeNext就能訂閱,
//subscribeNext:方法就提供了一個(gè)block,
//在每個(gè)next事件到達(dá)時(shí)執(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)建兩個(gè)發(fā)送布爾值的信號(hào)validUsernameSignal、validPasswordSignal
  //對(duì)用戶名和密碼的輸入進(jìn)行驗(yàn)證。
  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]);
   }];
  //信號(hào)合成
  //接下來(lái)的任務(wù)就是合成這兩個(gè)信號(hào),用以共同決定登錄按鈕是否可用
  RACSignal *signUpActiveSignal =
  [RACSignal combineLatest:@[validUsernameSignal, validPasswordSignal]
                    reduce:^id(NSNumber *usernameValid, NSNumber *passwordValid) {
                      return @([usernameValid boolValue] && [passwordValid boolValue]);
                    }];
  //上面的代碼使用combineLatest:reduce:方法   (RACSignal合成方法可以合成任意數(shù)量的信號(hào))
  //獲取validUsernameSignal和validPasswordSignal的最近一個(gè)信號(hào)值并組合成一個(gè)全新的信號(hào)。
  //每當(dāng)兩個(gè)源信號(hào)的其中一個(gè)發(fā)送新值,
  //reduce里的block代碼塊就會(huì)執(zhí)行(reduce中 block的入?yún)⒑驮葱盘?hào)一一對(duì)應(yīng))
  //其返回的值會(huì)作為合成信號(hào)的值發(fā)送出去。
  
  //最后是訂閱
  [signUpActiveSignal subscribeNext:^(NSNumber *signupActive) {
    self.signinBnt.enabled = [signupActive boolValue];
  }];

Second Demo

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

Demo地址

參考鏈接

Reactive github
美團(tuán)的幾篇博客
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)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容