RAC之常用方法-----新手入门
公司开发在使用RAC,之前居然一直没有了解过,独立开发的弊端,信息闭塞,而且自己也懒,这几天看了下RAC,确实很强大有木有。
什么是ARC
简单的说,RAC就是一个第三方库,他可以大大简化你的代码过程。
官方的说,ReactiveCocoa(其简称为RAC)是由GitHub开源的一个应用于iOS和OS X开发的新框架。RAC具有函数式编程和响应式编程的特性。
为什么我们要学习RAC?
为了提高我们的开发效率。RAC在某些特定情况下开发时可以大大简化代码,并且目前来看安全可靠。
配置RAC环境
我习惯用cocoapods来安装github上得开源库,推荐大家使用2.5.0版本以下的RAC
1 platform :ios, ‘8.0’ 2 target “RAC-Text” do 3 4 pod 'ReactiveCocoa', '~> 2.5' 5 6 end
信号signal是RAC的绝对核心,所有的操作都是围绕着信号来处理的。
比如:创建信号,订阅信号,发送信号是消息发送的核心步骤。
常见的三个信号类为:
- RACSignal
- RACSubject
- RACReplaySubject
RACSiganl:信号类,一般表示将来有数据传递,只要有数据改变,信号内部接收到数据,就会马上发出数据。
ReactiveCocoa开发中常见用法
1 代替代理.
rac_signalForSelector:
用于替代代理。
首先要说的:用RAC写代理是有局限的,它只能实现返回值为void的代理方法
1 UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"RAC" message:@"RAC TEST" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"other", nil]; 2 [[self rac_signalForSelector:@selector(alertView:clickedButtonAtIndex:) fromProtocol:@protocol(UIAlertViewDelegate)] subscribeNext:^(RACTuple *tuple) { 3 NSLog(@"%@",tuple.first); 4 NSLog(@"%@",tuple.second); 5 NSLog(@"%@",tuple.third); 6 }]; 7 [alertView show];
我们来看RAC的语句。@selector
是指这次事件监听的方法fromProtocol
指依赖的代理。这里block中有一个RACTuple,他相当于是一个集合类,他下面的first,second等就是类的各个参数,我这里点了AlertView第二个按钮other输出了一下。
1 2016-01-04 18:24:29.114 RACStudyTest[5003:388870] <UIAlertView: 0x7ff260c90c70; frame = (0 0; 0 0); layer = <CALayer: 0x7ff260c91030>> 2 2016-01-04 18:24:29.115 RACStudyTest[5003:388870] 1 3 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的序号了,可以直接应对我上述遇到的问题。
2代替KVO :
rac_valuesAndChangesForKeyPath:
用于监听某个对象的属性改变。
RAC中得KVO大部分都是宏定义,所以代码异常简洁,简单来说就是RACObserve(TARGET, KEYPATH)
这种形式,TARGET是监听目标,KEYPATH是要观察的属性值,这里举一个很简单的例子,如果UIScrollView滚动则输出success。
1 UIScrollView *scrolView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 200, 400)]; 2 scrolView.contentSize = CGSizeMake(200, 800); 3 scrolView.backgroundColor = [UIColor greenColor]; 4 [self.view addSubview:scrolView]; 5 [RACObserve(scrolView, contentOffset) subscribeNext:^(id x) { 6 NSLog(@"success"); 7 }];
3 监听事件:
rac_signalForControlEvents:
用于监听某个事件。
1 // 把按钮点击事件转换为信号,点击按钮,就会发送信号 2 [[self.btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) { 3 NSLog(@"按钮被点击了"); 4 }];
给Lable或者View添加监听
1 UILabel *textLab = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 200, 30)];
2 textLab.backgroundColor = [UIColor greenColor];
3 textLab.text = @"********************";
4 textLab.userInteractionEnabled = YES;
5 [self.view addSubview:textLab];
6
7
8 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] init];
9 [[tap rac_gestureSignal] subscribeNext:^(id x) {
10 NSLog(@"点击Lab");
11 }];
12 [textLab addGestureRecognizer:tap];
点击lab控制台会输出 :点击Lab
4 代替通知:
rac_addObserverForName:
用于监听某个通知。
在我们的开发中通知也是一个比较常用的功能,主要的应用场景是某个页面进行数据重传需要更新model但是点击返回栈时不会刷新返回界面的数据,这时就可以用通知来更新另一个页面的数据
首先,在某个页面中我们需要发出通知,这里就是最基本的通知的写法。发送名为postdata的通知并传送一个数组dataArray
1 NSMutableArray *dataArray = [[NSMutableArray alloc] initWithObjects:@"1", @"2", @"3", nil]; 2 [[NSNotificationCenter defaultCenter] postNotificationName:@"postData" object:dataArray];
而在接受的页面我们需要增加观察者并接受数组,这时我们的RAC就派上用场了。
1 [[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"postData" object:nil] subscribeNext:^(NSNotification *notification) { 2 NSLog(@"%@", notification.name); 3 NSLog(@"%@", notification.object); 4 }];
当这个页面监听到名为postdata的通知时他就会执行block中的方法,当然这里的参数改成id x
也是可以的,这里用NSNotification主要是强调它的类型。让我们看看控制台的输出
1 2016-01-04 20:10:52.274 RACStudyTest[5918:439077] postData 2 2016-01-04 20:10:52.275 RACStudyTest[5918:439077] ( 3 1, 4 2, 5 3 6 )
可见,notification.object就是我们想要的数组,当然我们也可以传一些model。值得一提的是,RAC中的通知不需要remove observer
,因为在rac_add方法中他已经写了remove。
5 监听文本框文字改变:
rac_textSignal:
只要文本框发出改变就会发出这个信号。
1 UITextField *text1 = [[UITextField alloc] initWithFrame:CGRectMake(100, 200, 200, 30)]; 2 text1.backgroundColor = [UIColor cyanColor]; 3 [self.view addSubview:text1]; 4 5 [[text1 rac_textSignal] subscribeNext:^(id x) { 6 static int i = 0; 7 i++; 8 // text改变就会打印 9 NSLog(@"厉害了我的哥------ %d", i); 10 }];
6 处理当界面有多次请求时,需要都获取到数据时,才能展示界面
rac_liftSelector:withSignalsFromArray:Signals:
当传入的Signals(信号数组),每一个signal都至少sendNext过一次,就会去触发第一个selector参数的方法。
使用注意:几个信号,参数一的方法就几个参数,每个参数对应信号发出的数据。
1 // 处理多个请求,都返回结果的时候,统一做处理. 2 RACSignal *request1 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { 3 // 发送请求1 4 [subscriber sendNext:@"发送请求1"]; 5 return nil; 6 }]; 7 8 RACSignal *request2 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { 9 // 发送请求2 10 [subscriber sendNext:@"发送请求2"]; 11 return nil; 12 }]; 13 14 // 使用注意:几个信号,参数一的方法就几个参数,每个参数对应信号发出的数据。 15 [self rac_liftSelector:@selector(updateUIWithR1:r2:) withSignalsFromArray:@[request1,request2]]; 16 } 17 // 更新UI(该方法有要求,有多少个信号就要求有多少个参数,参数的内容就是发送的数据。) 18 - (void)updateUIWithR1:(id)data r2:(id)data1 19 { 20 NSLog(@"更新UI%@,%@",data,data1); 21 }
内容来自网络摘抄和总结
http://www.jianshu.com/p/769025368bcb
http://www.cnblogs.com/qiyer/p/5483162.html
http://www.jianshu.com/p/ff79a5ae0353