ITKeyword,专注技术干货聚合推荐

注册 | 登录

IOS响应式编程框架ReactiveCocoa(RAC)

yujianxiang666 分享于 2015-03-19

推荐:【iOS架构】iOS ReactiveCocoa函数响应式编程

声明式编程 声明式编程(declarative programming)是一种编程范型,与命令式编程相对立。它描述目标的性质,让电脑明白目标,而非流程。声明式编程不用告诉电脑

2019阿里云双11返场狂欢继续,
地址https://www.aliyun.com/1111/2019/home

 ReactiveCocoa是响应式编程(FRP)在IOS中的一个实现框架,它的开源地址为:https://github.com/ReactiveCocoa/ReactiveCocoa# ;项目中有需要时可以直接搬过去用,用的熟练了再读源码也比较容易理解。


    例1. 监听对象的成员变量变化,当成员变量值被改变时,触发做一些事情。

    这种情况其实就是IOS KVO机制使用的场景,使用KVO实现,通常有三个步骤:1,给对象的成员变量添加监听;2,实现监听回调;3,取消监听;而通过RAC可以直接实现,RAC的回调是通过block实现的,类似于过程式编程,上下文也更容易理解一些。

    场景:当前类有一个成员变量 NSString *input,当它的值被改变时,发送一个请求。

    实现: 

[objc] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. [RACObserve(self, input)  
  2.     subscribeNext:^(NSString* x){  
  3.         request(x);//发送一个请求  
  4.    }];  

每次input值被修改时,就会调用此block,并且把修改后的值做为参数传进来。

 

场景:在上面场景中,当用户输入的值以2开头时,才发请求.

实现:

推荐:异步编程与响应式框架

前言 异步操作是强大的,它是许多高伸缩性架构的基石。异步操作在许多情况下是必须的,例如在客户端保持用户界面的响应能力,以及在日益兴起的云计算场景中。但

[objc] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. [[RACObserve(self, input)  
  2.      filter:^(NSString* value){  
  3.          if ([value hasPrefix:@"2"]) {  
  4.              return YES;  
  5.          } else {  
  6.              return NO;  
  7.          }  
  8.      }]  
  9.      subscribeNext:^(NSString* x){  
  10.         request(x);//发送一个请求  
  11.     }];  

场景:上面场景是监听自己的成员变量,如果想监听UITextField输入值变化,框架也做了封装可以代替系统回调

实现:

[objc] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. [[self.priceInput.rac_textSignal  
  2.      filter:^(NSString *str) {  
  3.          if (str.integerValue > 20) {  
  4.              return YES;  
  5.          } else {  
  6.              return NO;  
  7.          }  
  8.      }]  
  9.      subscribeNext:^(NSString *str) {  
  10. <span style="white-space:pre">    </span>request(x);//发送一个请求  
}];例2. 同时监听多个变量变化,当这些变量满足一定条件时,使button为可点击状态

场景:button监听 两个输入框有值和一个成员变量值,当输入框有输入且成员变量为真时,button为可点击状态

实现:

 

[objc] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. RAC(self.payButton,enabled) = [RACSignal  
  2.                                    combineLatest:@[self.priceInput.rac_textSignal,  
  3.                                                 self.nameInput.rac_textSignal,  
  4.                                                 RACObserve(self, isConnected)  
  5.                                                 ]  
  6.                                    reduce:^(NSString *price, NSString *name, NSNumber *connect){  
  7.                                    return @(price.length > 0 && name.length > 0 && [connect boolValue]);  
  8.                                    }];  

场景:满足上面条件时,直接发送请求

实现:

[objc] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. [[RACSignal  
  2.                                    combineLatest:@[self.priceInput.rac_textSignal,  
  3.                                                 self.nameInput.rac_textSignal,  
  4.                                                 RACObserve(self, isConnected)  
  5.                                                 ]  
  6.                                    reduce:^(NSString *price, NSString *name, NSNumber *connect){  
  7.                                    return @(price.length > 0 && name.length > 0 && ![connect boolValue]);  
  8.                                    }]  
  9.                              subscribeNext:^(NSNumber *res){  
  10.                                  if ([res boolValue]) {  
  11.                                      NSLog(@"XXXXX send request");  
  12.                                  }  
  13.                              }];  

例3. 类似于生成产-消费

场景:用户每次在TextField中输入一个字符,1秒内没有其它输入时,去发一个请求。TextField中字符改变触发事件已在例1中展示,这里实现一下它触法的方法,把1秒延时在此方法中实现。

实现:

[objc] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. - (void)showLoading {  
  2.   
  3.     [self.loadingDispose dispose];//上次信号还没处理,取消它(距离上次生成还不到1秒)  
  4.     @weakify(self);  
  5.     self.loadingDispose = [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {  
  6.         [subscriber sendCompleted];  
  7.         return nil;  
  8.     }] delay:1] //延时一秒  
  9.     subscribeCompleted:^{  
  10.         @strongify(self);  
  11.         doRequest();  
  12.         self.loadingDispose = nil;  
  13.     }];  
  14. }  

上面代码看起来挻费解,不过下面一段类似的代码拆开写的,会比较容易理解: [objc] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. [self.loadingDispose dispose];  
  2.       
  3.     RACSignal *loggingSignal = [RACSignal createSignal:^ RACDisposable * (id<RACSubscriber> subscriber) {//BLOCK_1  
  4.         subscriptions++;  
  5.         [subscriber sendNext:@"mytest"];  
  6.         [subscriber sendCompleted];  
  7.         return nil;  
  8.     }];  
  9.       
  10.     loggingSignal = [loggingSignal delay:10];  
  11.       
  12.     self.loadingDispose = [loggingSignal subscribeNext:^(NSString* x){//BLOCK_2  
  13.         NSLog(@"%@",x);  
  14.         NSLog(@"subscription %u", subscriptions);  
  15.     }];  
  16.       
  17.     self.loadingDispose = [loggingSignal subscribeCompleted:^{//BLOCK_3  
  18.         NSLog(@"subscription %u", subscriptions);  
  19.     }];  

loggingSignal在每次被调用subscriibeNext:^(id x)或subscribeCompleted:^方法时(12行和17行),它创建进传进的参数block_1就会被触动发,而block_1中的sendNext:方法会调用subscriibeNext:^中对应的block_2, 而block_1中的sendCompleted会调用subscribeCompleted:中对应的block_3


出处:http://blog.csdn.net/dfqin/article/details/39164241

推荐:使用ReactiveCocoa实现iOS平台响应式编程

 http://www.itiger.me/p=38 ReactiveCocoa和响应式编程 在说ReactiveCocoa之前,先要介绍一下FRP(Functional Reactive Programming,响应式编程),在维基百

 ReactiveCocoa是响应式编程(FRP)在IOS中的一个实现框架,它的开源地址为:https://github.com/ReactiveCocoa/ReactiveCocoa# ;项目中有需要时可以直接搬过去用,用的熟练了再读源码也比较容易

相关阅读排行


用户评论

游客

相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。