IOS响应式编程框架ReactiveCocoa(RAC)使用示例

原创 2014年09月11日 01:04:49

    ReactiveCocoa是响应式编程(FRP)在IOS中的一个实现框架,它的开源地址为:https://github.com/ReactiveCocoa/ReactiveCocoa# ;在网上看了几篇文章,感觉理论讲了很多,但是代码还是看不太懂,于是自己把它github文档上的一些使用的经典示例实现了一下,项目中有需要时可以直接搬过去用,用的熟练了再读源码也比较容易理解。


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

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

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

    实现: 

[RACObserve(self, input)
    subscribeNext:^(NSString* x){
        request(x);//发送一个请求
   }];

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

 

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

实现:

[[RACObserve(self, input)
     filter:^(NSString* value){
         if ([value hasPrefix:@"2"]) {
             return YES;
         } else {
             return NO;
         }
     }]
     subscribeNext:^(NSString* x){
        request(x);//发送一个请求
    }];

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

实现:

[[self.priceInput.rac_textSignal
     filter:^(NSString *str) {
         if (str.integerValue > 20) {
             return YES;
         } else {
             return NO;
         }
     }]
     subscribeNext:^(NSString *str) {
<span style="white-space:pre">	</span>request(x);//发送一个请求
}];


例2. 同时监听多个变量变化,当这些变量满足一定条件时,使button为可点击状态

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

实现:

 

RAC(self.payButton,enabled) = [RACSignal
                                   combineLatest:@[self.priceInput.rac_textSignal,
                                                self.nameInput.rac_textSignal,
                                                RACObserve(self, isConnected)
                                                ]
                                   reduce:^(NSString *price, NSString *name, NSNumber *connect){
                                   return @(price.length > 0 && name.length > 0 && [connect boolValue]);
                                   }];

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

实现:

[[RACSignal
                                   combineLatest:@[self.priceInput.rac_textSignal,
                                                self.nameInput.rac_textSignal,
                                                RACObserve(self, isConnected)
                                                ]
                                   reduce:^(NSString *price, NSString *name, NSNumber *connect){
                                   return @(price.length > 0 && name.length > 0 && ![connect boolValue]);
                                   }]
                             subscribeNext:^(NSNumber *res){
                                 if ([res boolValue]) {
                                     NSLog(@"XXXXX send request");
                                 }
                             }];

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

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

实现:

- (void)showLoading {

    [self.loadingDispose dispose];//上次信号还没处理,取消它(距离上次生成还不到1秒)
    @weakify(self);
    self.loadingDispose = [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber sendCompleted];
        return nil;
    }] delay:1] //延时一秒
    subscribeCompleted:^{
        @strongify(self);
        doRequest();
        self.loadingDispose = nil;
    }];
}

上面代码看起来挻费解,不过下面一段类似的代码拆开写的,会比较容易理解:

[self.loadingDispose dispose];
    
    RACSignal *loggingSignal = [RACSignal createSignal:^ RACDisposable * (id<RACSubscriber> subscriber) {//BLOCK_1
        subscriptions++;
        [subscriber sendNext:@"mytest"];
        [subscriber sendCompleted];
        return nil;
    }];
    
    loggingSignal = [loggingSignal delay:10];
    
    self.loadingDispose = [loggingSignal subscribeNext:^(NSString* x){//BLOCK_2
        NSLog(@"%@",x);
        NSLog(@"subscription %u", subscriptions);
    }];
    
    self.loadingDispose = [loggingSignal subscribeCompleted:^{//BLOCK_3
        NSLog(@"subscription %u", subscriptions);
    }];

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


ReactiveCocoa之RAC合并(九)

@interface ViewController () @property (weak, nonatomic) IBOutlet UITextField *accountField; @proper...
  • y_csdnblog_xx
  • y_csdnblog_xx
  • 2016年05月23日 11:51
  • 4007

RAC(二)

什么是信号 RAC的核心就是信号,即RACSignal。 信号可以看做是传递信号的工具,当数据变化时,信号就会发送改变的信息,以通知信号的订阅者执行方法。 热/冷信号 默认一个信号都是冷信号,也...
  • shubinniu
  • shubinniu
  • 2016年11月28日 14:08
  • 608

Oracle11gR2 RAC for Windows安装上篇:Grid Infrastructure + ASM 两节点安装 简要步骤及安装问题总结

一、关闭防火墙 二、修改计算机名 三、修改服务器密码 四、配置双网卡优先级和IP 五、共享C盘 六、配置共享磁盘 七、安装Grid Infrastructure...
  • blvyoucan
  • blvyoucan
  • 2017年05月05日 15:33
  • 2756

11G RAC 重启步骤

from:http://blog.163.com/yanenshun@126/blog/static/128388169201368112253346/ 系统的检修时间到了,新添了一套11G RAC...
  • shangxinyu0907
  • shangxinyu0907
  • 2014年01月08日 09:55
  • 1474

oracle rac 的优点和缺点

oracle rac 是oracle公司 推出的 数据库 集群方案。 oracle RAC 是共享存储的集群方案。 - 优点一、多机并行 oracle rac 支持多台服务器共同对外...
  • zdc524
  • zdc524
  • 2016年01月14日 10:49
  • 4127

什么是RAC集群。

1、集群环境的特殊问题 健忘症:这个问题发生在集群环境配置文件不是集中存放,而是每个节点都有一个本地副本。在集群正常运行时,用户可以在任何节点修改集群的配置,并且这个更改会自动同步到其他节点。但...
  • zq9017197
  • zq9017197
  • 2012年06月06日 11:29
  • 6830

RAC初识

简介简单的说,RAC就是一个第三方库,他可以大大简化你的代码过程。官方的说,ReactiveCocoa(其简称为RAC)是由GitHub开源的一个应用于iOS和OS X开发的新框架。RAC具有函数式编...
  • liyanjun201
  • liyanjun201
  • 2017年12月21日 15:55
  • 46

RAC的基本使用

RAC其实可以帮我们做的事情很多很多,而且也很简单,并且代码和流水线一样这样下来也很好的阅读,能把业务逻辑放到一块进行处理,接下来就来简单的介绍下 这里使用的版本是ReactiveObjC 3.0.0...
  • ZCMUCZX
  • ZCMUCZX
  • 2017年12月28日 13:08
  • 128

ReactiveCocoa之RAC常用宏(十)

/** * RAC有许多强大而方便的宏。 */ - (void)viewDidLoad { [super viewDidLoad]; // Do any additional ...
  • y_csdnblog_xx
  • y_csdnblog_xx
  • 2016年05月23日 11:53
  • 1403

RACOBserve绑定收不到信号

今天遇到了一个奇怪的问题,先看一下代码: //视图模型 @interface ContactsVM : NSObject @property (nonatomic, strong) NSMuta...
  • gx_wqm
  • gx_wqm
  • 2016年05月11日 18:06
  • 1297
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:IOS响应式编程框架ReactiveCocoa(RAC)使用示例
举报原因:
原因补充:

(最多只允许输入30个字)