zoukankan      html  css  js  c++  java
  • RAC初体验

    什么是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,这些都是我给自己留得坑,以后也会发文介绍给大家。也欢迎来我的博客看看。

     
  • 相关阅读:
    LeetCode Binary Tree Inorder Traversal
    LeetCode Populating Next Right Pointers in Each Node
    LeetCode Construct Binary Tree from Inorder and Postorder Traversal
    LeetCode Reverse Linked List II
    LeetCode Populating Next Right Pointers in Each Node II
    LeetCode Pascal's Triangle
    Palindrome Construct Binary Tree from Preorder and Inorder Traversal
    Pascal's Triangle II
    LeetCode Word Ladder
    LeetCode Binary Tree Zigzag Level Order Traversal
  • 原文地址:https://www.cnblogs.com/YRFios/p/5238100.html
Copyright © 2011-2022 走看看