IOS RAC(ReactiveCocoa) -Functional Reactive Programming 详解[转载ReactiveCocoa与Functional Reactive Prog]

来源:互联网 发布:npm install淘宝 编辑:程序博客网 时间:2024/05/22 05:26

这是写得很好的文章,转载分享,给自己也做个笔记学习

ReactiveCocoa与Functional Reactive Programming

什么是Functional Reactive Programming

Functional Reactive Programming(以下简称FRP)是一种响应变化的编程范式。先来看一小段代码

a = 2b = 2c = a + b // c is 4b = 3// now what is the value of c?

如果使用FRP,c的值将会随着b的值改变而改变,所以叫做「响应式编程」。比较直观的例子就是Excel,当改变某一个单元格的内容时,该单元格相关的计算结果也会随之改变。

FRP提供了一种信号机制来实现这样的效果,通过信号来记录值的变化。信号可以被叠加、分割或合并。通过对信号的组合,就不需要去监听某个值或事件。

FRP demo

这在重交互的应用里是非常有用的。以注册为例:

register demo

提交按钮的状态要跟输入框的状态绑定,比如必选的输入框没有填完时,提交按钮是灰色的,也就是不可点;如果提交按钮不可点,那么文字变成灰色,不然变成蓝色;如果正在提交,那么输入框的文字颜色变成灰色,且不可点,不然变成默认色且可点;如果注册成功就在状态栏显示成功信息,不然显示错误信息,等等。

可以看到光是注册页就有这么多的联动,在javascript中可以采用事件监听来处理,iOS中更多的是delegate模式,本质上都是事件的分发和响应。这种做法的缺点是不够直观,尤其在逻辑比较复杂的情况下。这也是为什么尽管nodejs很高效,但由于javascript的callback style和异步模式不符合正常的编程习惯,让很多人望而却步。

使用FRP主要有两个好处:直观和灵活。直观的代码容易编写、阅读和维护,灵活的特性便于应对变态的需求。

ReactiveCocoa

ReactiveCocoa是github去年开源的一个项目,是在iOS平台上对FRP的实现。FRP的核心是信号,信号在ReactiveCocoa(以下简称RAC)中是通过RACSignal来表示的,信号是数据流,可以被绑定和传递。

可以把信号想象成水龙头,只不过里面不是水,而是玻璃球(value),直径跟水管的内径一样,这样就能保证玻璃球是依次排列,不会出现并排的情况(数据都是线性处理的,不会出现并发情况)。水龙头的开关默认是关的,除非有了接收方(subscriber),才会打开。这样只要有新的玻璃球进来,就会自动传送给接收方。可以在水龙头上加一个过滤嘴(filter),不符合的不让通过,也可以加一个改动装置,把球改变成符合自己的需求(map)。也可以把多个水龙头合并成一个新的水龙头(combineLatest:reduce:),这样只要其中的一个水龙头有玻璃球出来,这个新合并的水龙头就会得到这个球。

下面通过一个简单的demo来演示这个模型。

假如对象的某个属性想绑定某个消息,可以使用RAC这个宏,相当于给玻璃球套了一个水龙头。

RAC(self.submitButton, enabled) = [RACSignal combineLatest:@[self.usernameField.rac_textSignal, self.passwordField.rac_textSignal] reduce:^id(NSString *userName, NSString *password) {    return @(userName.length >= 6 && password.length >= 6);}];

这样,如果用户名和密码框的长度都超过6,提交按钮就enable了。反之,如果没符合要求,就会处于非开启状态。

可以看到usernameField有了一个新的属性rac_textSignal,这是RAC在UITextFieldcategory中添加的,直接用即可。

combine signal

RAC的大统一

RAC统一了对KVO、UI Event、Network request、Async work的处理,因为它们本质上都是值的变化(Values over time)。

KVO

RAC可以用来监测属性的改变,这点跟KVO很像,不过使用了block,而不是-observeValueForKeyPath:ofObject:change:context:

[RACAble(self.username) subscribeNext:^(NSString *newName) {    NSLog(@"%@", newName);}];

使用起来是不是比KVO舒服多了。比KVO更加强大的是信号可以被链起来(chain)

// 只有当名字以'j'开头,才会被记录[[RACAble(self.username)   filter:^(NSString *newName) {       return [newName hasPrefix:@"j"];   }]   subscribeNext:^(NSString *newName) {       NSLog(@"%@", newName);   }];

UI Event

RAC还为系统UI提供了很多category,来方便消息的创建和传递,比如按钮被点击或文本框有改动等等,上面的例子中self.firstNameField.rac_textSignal,在对应的文本框有改动时,会自动向数据流中添加新的数据,绑定该消息的其他消息就会收到新的数据,如果有subscriber的话,会自动触发。

Network Request && Async work

这些可以通过自定义信号,也就是RACSubject(继承自RACSignal,可以理解为自由度更高的signal)来搞定。比如一个异步网络操作,可以返回一个subject,然后将这个subject绑定到一个subscriber或另一个信号。

- (void)doTest{    RACSubject *subject = [self doRequest];        [subject subscribeNext:^(NSString *value){        NSLog(@"value:%@", value);    }];}- (RACSubject *)doRequest{    RACSubject *subject = [RACSubject subject];    // 模拟2秒后得到请求内容    // 只触发1次    // 尽管subscribeNext什么也没做,但如果没有的话map是不会执行的    // subscribeNext就是定义了一个接收体    [[[[RACSignal interval:2] take:1] map:^id(id _){        // the value is from url request        NSString *value = @"content fetched from web";        [subject sendNext:value];        return nil;    }] subscribeNext:^(id _){}];    return subject;}

小结

简单画了下关系图,罗列了些要点

关系图和要点

上面只是大概说了一下RAC的使用情景和用法,更多的例子可以到项目主页中查看。

参考

  • http://www.teehanlax.com/blog/getting-started-with-reactivecocoa/
  • https://speakerdeck.com/andrewsardone/reactivecocoa-at-mobidevday-2013

--EOF--
转载链接: http://limboy.me/ios/2013/06/19/frp-reactivecocoa.html

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 摩托罗拉电话静音了怎么办 对讲机话筒坏了怎么办 摩托罗拉xt1570费电怎么办 主板没有rgb接口怎么办 对讲机频段没了怎么办 怀孕查出宫颈囊怎么办 办养殖场没地怎么办 宝宝睡觉衣服湿透怎么办 开衫衣服往下滑怎么办 迷你世界没有牛怎么办 火龙果树烂了怎么办 误喝鸵鸟墨水怎么办 被鸵鸟啄伤怎么办 被鸵鸟啄住怎么办 鸟翅膀受伤了怎么办 北京卖房户口怎么办 深户挂人才市场集体户小孩怎么办? 郑州房子限购怎么办 外地怎么送东西怎么办 晚上登华山下雨怎么办 北京摇不到号想买车怎么办 北京买车摇不到号怎么办 朋友代购贵了怎么办 赢时通把车开走怎么办 杭州房子租不起怎么办 质量效应2吵架怎么办 学生有两个学籍怎么办 孩子出现双学籍怎么办 在外地读书学籍怎么办 上高中没学籍怎么办 电信欠费了网络怎么办 头发里长脓包怎么办 工作总是做不好怎么办 能力差的人该怎么办 洗衣机里有味道怎么办 洗衣机里面有味道怎么办 洗衣机内有味道怎么办 洗衣机总有味道怎么办 上体育课脚扭伤怎么办 教学实践评价表怎么办 初中孩子成绩下降怎么办