原文:http://www.jianshu.com/p/ff79a5ae0353

什么是RAC?

几乎每一篇介绍RAC的文章开头都是这么一个问题。我这篇文章是写给新手(包括我自己)看的,所以这个问题更是无法忽视。

简单的说,RAC就是一个第三方库,他可以大大简化你的代码过程。

官方的说,ReactiveCocoa(其简称为RAC)是由GitHub开源的一个应用于iOS和OS X开发的新框架。RAC具有函数式编程响应式编程的特性。

为什么我们要学习RAC?

为了提高我们的开发效率。RAC在某些特定情况下开发时可以大大简化代码,并且目前来看安全可靠。

配置RAC环境

我习惯用cocoapods来安装github上得开源库,不会的新手iOS开发者有兴趣可以去学一下。

想学习cocoapods的同学推荐唐巧前辈的文章

platform:ios, '8.0'
pod 'ReactiveCocoa','~>2.1.8'

这里有一点要注意下就是RAC的版本问题,由于还没学习Swift,所以我是用OC编写程序的,最新版的RAC已经支持Swift了,但是在OC的程序安装最新版的RAC可能跑不起来,所以推荐大家使用2.5.0版本以下的RAC(具体支持Swift的版本可能有误,但我引用的2.1.8肯定是没问题的)。

使用RAC

1.target-action

RAC最基本的入门使用技巧就是对事件的监听。

PS:在iOS开发中,我们所说的点击事件其实就是target-action,接触过iOS开发的人都不会陌生UIControlEventTouchUpInside,这就是按下并松开的动作。不仅仅是UIButton,还有UITextField也有目标-动作模式。

使用前别忘了引用头文件~

#import <ReactiveCocoa/ReactiveCocoa.h>

接下来就是最关键的RAC代码了。

[[self.textFild rac_signalForControlEvents:UIControlEventEditingChanged] subscribeNext:^(id x){
NSLog(@"change");
}];

就这么短短的两行代码。他实现了一个功能,即监听了textFild的UIControlEventEditingChanged事件,当事件发生时实现方法NSLog
所以我们就可以以这段代码为模板进行RAC的使用,举一反三,以后的UIButton点击事件我们都可以用RAC方法进行添加,再也不用add Target了。
对于textFild的文字更改监听也有更简单的写法

[[self.textFild rac_textSignal] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];

这样就是每次改变TextFild都输出改变后的结果。

再比如给我们的某个label添加一个手势动作,我们也可以用简单的RAC代码完成

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] init];
[[tap rac_gestureSignal] subscribeNext:^(id x) {
NSLog(@"tap");
}];
[self.view addGestureRecognizer:tap];

这段具体我就不解释了,相信大家都能看得懂,看不懂的自己写写就懂了。

2.代理

用RAC写代理是有局限的,它只能实现返回值为void的代理方法

首先我们要明白我们为什么要用RAC写代理?答:简化代码!是的,的确为了简化代码,为什么我要再这里强调这个,是因为在代理方法中我深深的感受到了RAC的优点。一开始我也不愿意花功夫去学RAC,但是我师父给我举了一个例子,如果一个View里有多个AlertView,每个AlertView有很多个按钮,每个按钮都有自己的点击事件,我应该怎么写?我想了一下,不但每个按钮需要打标记,而且每个AlertView也要打标记,然后再往代理点击事件里加各种方法,代码就又臭又长。那么让我们看看RAC怎么写代理方法。

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"RAC" message:@"RAC TEST" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"other", nil];
[[self rac_signalForSelector:@selector(alertView:clickedButtonAtIndex:) fromProtocol:@protocol(UIAlertViewDelegate)] subscribeNext:^(RACTuple *tuple) {
NSLog(@"%@",tuple.first);
NSLog(@"%@",tuple.second);
NSLog(@"%@",tuple.third);
}];
[alertView show];

  

我们来看RAC的语句。@selector是指这次事件监听的方法fromProtocol指依赖的代理。这里block中有一个RACTuple,他相当于是一个集合类,他下面的first,second等就是类的各个参数,我这里点了AlertView第二个按钮other输出了一下。

2016-01-04 18:24:29.114 RACStudyTest[5003:388870] <UIAlertView: 0x7ff260c90c70; frame = (0 0; 0 0); layer = <CALayer: 0x7ff260c91030>>
2016-01-04 18:24:29.115 RACStudyTest[5003:388870] 1
2016-01-04 18:24:29.115 RACStudyTest[5003:388870] (null)

  

可以看出tuple.second是ButtonAtIndex中Button的序号。那么对于上面那个我举的例子,就可以用switch给各个按钮添加方法,这样的代码看起来更容易理解,方面后期维护。

当然了,AlertView代理也有简化的代码。

[[alertView rac_buttonClickedSignal] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];

  

这里的x就是各个Button的序号了,可以直接应对我上述遇到的问题。

3.通知

在我们的开发中通知也是一个比较常用的功能,主要的应用场景是某个页面进行数据重传需要更新model但是点击返回栈时不会刷新返回界面的数据,这时就可以用通知来更新另一个页面的数据,当然我们也可以在另一个页面的ViewDidAppear方法中刷新数据,但那是题外话。

这里写的Demo就是我上述说的情况。

首先,在某个页面中我们需要发出通知,这里就是最基本的通知的写法。发送名为postdata的通知并传送一个数组dataArray。

NSMutableArray *dataArray = [[NSMutableArray alloc] initWithObjects:@"1", @"2", @"3", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"postData" object:dataArray];

  

而在接受的页面我们需要增加观察者并接受数组,这时我们的RAC就派上用场了。

[[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"postData" object:nil] subscribeNext:^(NSNotification *notification) {
NSLog(@"%@", notification.name);
NSLog(@"%@", notification.object);
}];

  

当这个页面监听到名为postdata的通知时他就会执行block中的方法,当然这里的参数改成id x也是可以的,这里用NSNotification主要是强调它的类型。让我们看看控制台的输出。

2016-01-04 20:10:52.274 RACStudyTest[5918:439077] postData
2016-01-04 20:10:52.275 RACStudyTest[5918:439077] (
1,
2,
3
)

  

可见,notification.object就是我们想要的数组,当然我们也可以传一些model。值得一提的是,RAC中的通知不需要remove observer因为在rac_add方法中他已经写了remove。

4.KVO

RAC中得KVO大部分都是宏定义,所以代码异常简洁,简单来说就是RACObserve(TARGET, KEYPATH)这种形式,TARGET是监听目标,KEYPATH是要观察的属性值,这里举一个很简单的例子,如果UIScrollView滚动则输出success。

UIScrollView *scrolView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 200, 400)];
scrolView.contentSize = CGSizeMake(200, 800);
scrolView.backgroundColor = [UIColor greenColor];
[self.view addSubview:scrolView];
[RACObserve(scrolView, contentOffset) subscribeNext:^(id x) {
NSLog(@"success");
}];

  

如果你好好回顾下KVO的写法会不会更加感叹RAC的强大呢?

总结

RAC的东西很多,但相信这篇文章给大家入门还是可以的,这里介绍了RAC得基本使用方法,但是还有很多好用的东西比如信号都没介绍,甚至除了subscribeNext还有subscribeComplete和subscribeError,这些都是我给自己留得坑,以后也会发文介绍给大家。

文/巴拉森(简书作者)
原文链接:http://www.jianshu.com/p/ff79a5ae0353
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

学习RAC小记-适合给新手看的RAC用法总结(转)的更多相关文章

  1. 适合 C++ 新手学习的开源项目——在 GitHub 学编程

    作者:HelloGitHub-小鱼干 俗话说:万事开头难,学习编程也是一样.在 HelloGitHub 的群里,经常遇到有小伙伴询问编程语言如何入门方面的问题,如: 我要学习某一门编程语言,有什么开源 ...

  2. STM32环境搭建/学习观点/自学方法 入门必看

    文章转自armfly开发板V4软件开发手册,分享学习~ 今天有幸看到armfly的开发板软件开发手册,开头的基础知识,真的很有用,还好有看到,一切都不迟,感悟很多,摘抄部分,学习分享~ 关于开发环境的 ...

  3. 给学习IT、编程者的看

    Preface: 我始终认为,对一个初学者来说,IT界的技术风潮...... Content: 我始终认为,对一个初学者来说,IT界的技术风潮是不可以追赶的,而且也没有能力去追赶.我时常看见自己的DD ...

  4. 小白学习VUE第一篇文章---如何看懂网上搜索到的VUE代码或文章---使用VUE的三种模式:

    小白学习VUE第一篇文章---如何看懂网上搜索到的VUE代码或文章---使用VUE的三种模式: 直接引用VUE; 将vue.js下载到本地后本目录下使用; 安装Node环境下使用; ant-desig ...

  5. Docker新手入门:基本用法

    Docker新手入门:基本用法 1.Docker简介 1.1 第一本Docker书 工作中不断碰到Docker,今天终于算是正式开始学习了.在挑选系统学习Docker以及虚拟化技术的书籍时还碰到了不少 ...

  6. 【Ext.Net学习笔记】06:Ext.Net GridPanel的用法(GridPanel 折叠/展开行、GridPanel Selection、 可编辑的GridPanel)

    GridPanel 折叠/展开行 Ext.Net GridPanel的行支持折叠/展开功能,这个功能个人觉得还说很有用处的,尤其是数据中包含图片等内容的时候. 下面来看看效果: 使用行折叠/展开功能之 ...

  7. 【Ext.Net学习笔记】05:Ext.Net GridPanel的用法(包含Filter、Sorter、Grouping、汇总(Summary)的用法)

    GridPanel是用来显示数据的表格,与ASP.NET中的GridView类似. GridPanel用法 直接看代码: <ext:GridPanel runat="server&qu ...

  8. Ext.Net学习笔记15:Ext.Net GridPanel 汇总(Summary)用法

    Ext.Net学习笔记15:Ext.Net GridPanel 汇总(Summary)用法 Summary的用法和Group一样简单,分为两步: 启用Summary功能 在Feature标签内,添加如 ...

  9. 【翻译自mos文章】检查$ORACLE_HOME是否是RAC的HOME的方法以及relink RAC的Oracle binary的方法

    检查$ORACLE_HOME是否是RAC的HOME的方法以及relink RAC的Oracle binary的方法 来源于: How to Check Whether Oracle Binary/In ...

随机推荐

  1. 【Robot Framework 介绍】总纲

    Robot Framework是一个由python构建的的开源的自动化测试框架,现在版本还在不停的更新中.由于它开源性,网上有大量的第三方接口和很多资料.下面提供两个比较官方的链接,有兴趣的同学可以直 ...

  2. mysqlbinlog 读取多个文件

    [root@zjzc01 binlog]# mysqlbinlog --start-datetime='2016-02-25 00:00:00' --stop-datetime='2016-03-15 ...

  3. Google map v3 using simple tool file google.map.util.js v 1.2

    更新添加日志:在1.1的基础上添加marker的文字显示.测距工具. /** * GOOGLE地图开发使用工具 * @author BOONYACHENGDU@GMAIL.COM * @date 20 ...

  4. #include <boost/bind.hpp>

    纯C++风格,没有使用#include <boost/bind.hpp> #include <iostream> #include <algorithm> #inc ...

  5. cocos2dx lua 学习笔记(一)

    macosx 安装 lua curl -R -O http://www.lua.org/ftp/lua-5.1.4.tar.gz tar zxf lua-5.1.4.tar.gz cd lua-5.1 ...

  6. mysql 相同表求解统一字段不同内容的交集

    SELECT id, bid, name, title, publisher FROM A where publisher in (select publisher from B group by B ...

  7. JavaScript中的setAttribute用法

    我们经常需要在JavaScript中给Element动态添加各种属性,这可以通过使用setAttribute()来实现,这就涉及到了浏览器的兼容性问题. setAttribute(string nam ...

  8. Android学习之sqlite与listview

    在android系统中使用的是sqlite数据库,前面的简易登录系统已经讲述了数据库的应用.本例的重点是实现数据库与listview的绑定.demo的数据是将个人的信息绑定到listview中,并存在 ...

  9. HTML网页制作:[12]使用框架结构之frameset

    首先,我希望在你的目录下,有4个网页,各自显示不同的内容. 如图所示: 1.html显示“火影忍者” 2.html显示“英雄联盟” 3.html显示“嵌入式开发.网页开发.安卓开发” 4.html显示 ...

  10. 详解JOIN

    根据连接中使用的操作符不同,连接条件可分为:等连接,不等连接   连接本身分为: 内连接(INNER JOIN) (1)INNER JOIN 方式(INNER可以省略) 取两表的交集. (2)并表查询 ...