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.02 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

posted @ 2017-03-02 11:31  Leo-Wmw  阅读(1958)  评论(1编辑  收藏  举报