ReactiveCocoa入门(一)
ReactiveCocoa的基本使用方法
ReactiveCocoa是github去年开源的一个项目,是在iOS平台上对FRP的实现。FRP的核心是信号,信号在ReactiveCocoa(以下简称RAC)中是通过RACSignal来表示的,信号是数据流,可以被绑定和传递。 可以把信号想象成水龙头,只不过里面不是水,而是玻璃球(value),直径跟水管的内径一样,这样就能保证玻璃球是依次排列,不会出现并排的情况(数据都是线性处理的,不会出现并发情况)。水龙头的开关默认是关的,除非有了接收方(subscriber),才会打开。这样只要有新的玻璃球进来,就会自动传送给接收方。可以在水龙头上加一个过滤嘴(filter),不符合的不让通过,也可以加一个改动装置,把球改变成符合自己的需求(map)。也可以把多个水龙头合并成一个新的水龙头(combineLatest:reduce:),这样只要其中的一个水龙头有玻璃球出来,这个新合并的水龙头就会得到这个球。
首先来看一个小例子
[self.input.rac_textSignal subscribeNext:^(id x){ NSLog(@"%@", x); }];
在这段代码以后,只要你的TextField中的值有变化。都可以打印出来。实现了KVO的功能却减少了无数的代码。体现了绑定和响应。
在这段代码的基础上我们还可以进行过滤 , 以下是第二个例子:
[[self.input.rac_textSignal filter:^BOOL(id value){ NSString*text = value; return text.length > 3; }] subscribeNext:^(id x){ NSLog(@"%@", x); }];
编译运行,在TextField只能输入字符,你会发现只有当输入超过3个字符时才会有打印输出。
RACSignal的每个操作都会返回一个RACsignal,这在术语上叫做连贯接口(fluent interface)。这个功能可以让你直接构建管道,而不用每一步都使用本地变量。
在上面的代码中,注释部分标记了将id隐式转换为NSString,这看起来不是很好看。幸运的是,传入block的值肯定是个NSString,所以你可以直接修改参数类型:
[[self.input.rac_textSignal filter:^BOOL(NSString*text){ return text.length > 3; }] subscribeNext:^(id x){ NSLog(@"%@", x); }];
第一个例子是简单的所有变化都会响应到。但是需求可能只需要响应部分情况。这时候就用filter来过滤。filter的block返回YES的情况就是需要触发的情况。其他就不返回。
组合
这个是用的leezhong的图
验证每个所填写的数值符合标准之后,Button才能点击。
RAC(self, self.btn.enabled) = [RACSignal combineLatest:@[self.usernameText.rac_textSignal, self.passwordText.rac_textSignal] reduce:^id (NSString *userName, NSString *password) { return @(userName.length >= 6 && password.length >= 6); }];
这段代码把usernameText和passwordText的信号绑定在了一起做reduce处理以后, 返回一个BOOL值去跟self.btn.enabled进行绑定
总结
以上仅仅是ReactiveCocoa最简单的用法, 自己的理解也不是很深入, 所以我会一直对ReactiveCocoa投入时间去学习和使用。
最后引用leezhong所说的一句话
RAC统一了对KVO、UI Event、Network request、Async work的处理,因为它们本质上都是值的变化(Values over time)。