美文网首页
RAC框架源码解析之常见用法

RAC框架源码解析之常见用法

作者: Jimi | 来源:发表于2018-04-21 18:52 被阅读23次

1、常见用法

1、代替代理
2、代替KVO
3、监听事件
4、代替通知
5、监听文本框

2、RAC代替代理

在OC中我们什么情况下会用到代理?一般会在多控制器传值或者自定义View的点击事件传递等

首先我们自定义一个View并在View中添加一个按钮,当按钮点击的时候如何传值?

-------------------- JMView.h --------------------
//
//  JMView.h
//  RAC常见用法
//
//  Created by JM on 2018/4/21.
//  Copyright © 2018年 JM. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface JMView : UIView

@end

-------------------- JMView.m --------------------
//
//  JMView.m
//  RAC常见用法
//
//  Created by JM on 2018/4/21.
//  Copyright © 2018年 JM. All rights reserved.
//

#import "JMView.h"

@implementation JMView

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
        [btn setTitle:@"点我" forState:UIControlStateNormal];
        [btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        btn.backgroundColor = [UIColor orangeColor];
        btn.frame = CGRectMake(10, 10, 100, 50);
        //按钮的点击事件
        [btn addTarget:self action:@selector(btnClick) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:btn];
    }
    return self;
}

- (void)btnClick {
    [self lailma:@"666"];
}

- (void)lailma:(NSString *)str {
    
}

@end

控制器中直接监听自定义View的点击事件

    [[self.jmView rac_signalForSelector:@selector(lailma:)] subscribeNext:^(RACTuple * _Nullable x) {
        NSLog(@"按钮被点击了----%@", x);
    }];

3、RAC代替KVO

我们都知道kvo的特性是当监听属性的值变化的时候就会走进observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context,那么如何用RAC实现呢!下面我们来监听自定义View的frame,当frame值变化的时候我们就走进自定义方法

控制器监听自定义View的frame,当我们点击屏幕的时候改变自定义View的frame,看在subscribeNext能不能监听到值的改变

//
//  ViewController.m
//  RAC常见用法
//
//  Created by JM on 2018/4/21.
//  Copyright © 2018年 JM. All rights reserved.
//

#import "ViewController.h"
#import "JMView.h"
#import <ReactiveObjC/ReactiveObjC.h>
#import <ReactiveObjC/NSObject+RACKVOWrapper.h>

//#import <NSObject+RACKVOWrapper.h>

@interface ViewController ()

/** jmView */
@property (nonatomic, strong) JMView *jmView;

@end

@implementation ViewController

- (JMView *)jmView {
    if (!_jmView) {
        _jmView = [[JMView alloc] initWithFrame:CGRectMake(10, 100, 300, 100)];
        _jmView.backgroundColor = [UIColor purpleColor];
        [self.view addSubview:_jmView];
    }
    return _jmView;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //RACKVO监听自定义view的frame方式1
    [[self.jmView rac_valuesForKeyPath:@"frame" observer:nil] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];

//    //RACKVO监听自定义view的frame方式2
//    self.jmView rac_observeKeyPath:@"frame" options:NSKeyValueObservingOptionOld | [NSKeyValueChangeNewKey observer:nil block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) {
//        NSLog(@"%@---%@",value, change);
//    }];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    self.jmView.frame = CGRectMake(10, 100, 310, 120);
}

@end

控制台输出结果

2018-04-21 16:44:40.993034+0800 RAC常见用法[45086:1889455] NSRect: {{10, 100}, {300, 100}}
2018-04-21 16:44:44.682167+0800 RAC常见用法[45086:1889455] NSRect: {{10, 100}, {310, 120}}

4、RAC监听事件

首先我们在控制器中创建一个按钮,用OC原生的方式使用addTarget: action: forControlEvents: 的方式,用RAC如何写?

//
//  ViewController.m
//  RAC常见用法
//
//  Created by JM on 2018/4/21.
//  Copyright © 2018年 JM. All rights reserved.
//

#import "ViewController.h"
#import "JMView.h"
#import <ReactiveObjC/ReactiveObjC.h>
#import <ReactiveObjC/NSObject+RACKVOWrapper.h>

//#import <NSObject+RACKVOWrapper.h>

@interface ViewController ()

/** btn */
@property (nonatomic, strong) UIButton *btn;

@end

@implementation ViewController

- (UIButton *)btn {
    if (!_btn) {
        _btn = [UIButton buttonWithType:UIButtonTypeCustom];
        _btn.backgroundColor = [UIColor orangeColor];
        [_btn setTitle:@"我是按钮" forState:UIControlStateNormal];
        [_btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        _btn.frame = CGRectMake(50, 100, 100, 50);
        [self.view addSubview:_btn];
    }
    return _btn;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    //监听事件(OC原生写法)
//    [self.btn addTarget:self action:@selector(btnClick) forControlEvents:UIControlEventTouchUpInside];
    //监听事件(RAC写法)
    [[self.btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
        NSLog(@"按钮被点击了---%@", x);
    }];
    
}
@end

控制器中输出并把当前的事件对象打印出来

2018-04-21 18:30:24.529704+0800 RAC常见用法[47170:1969057] 按钮被点击了---<UIButton: 0x7fee62e143c0; frame = (50 100; 100 50); opaque = NO; layer = <CALayer: 0x600000023820>>

5、RAC代替通知

用原声OC监听通知的时候使用addObserver: selector: name: object:];来监听通知并实现selector方法,通知使用完毕后还需销毁通知,但是RAC一行代码即可实现监听通知并且内置机制会自动销毁通知。

    //原生OC监听通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeEvent) name:@"evnet" object:nil];
    //RAC监听通知
    [[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"event" object:nil] subscribeNext:^(NSNotification * _Nullable x) {
        NSLog(@"%@",x);
    }];

6、RAC监听文本框

首先我们在控制器声明一个UITextFiled,如果用原生OC写法想实时监听输入框的值,有两种写法,1、遵守代理、实现代理。2、给输入框添加一个改变事件的方法。上述两种都比较麻烦,如果用RAC来实现那就显然要简单的多了。

//
//  ViewController.m
//  RAC常见用法
//
//  Created by JM on 2018/4/21.
//  Copyright © 2018年 JM. All rights reserved.
//

#import "ViewController.h"
#import "JMView.h"
#import <ReactiveObjC/ReactiveObjC.h>
#import <ReactiveObjC/NSObject+RACKVOWrapper.h>

//#import <NSObject+RACKVOWrapper.h>

@interface ViewController ()

/** tf */
@property (nonatomic, strong) UITextField *tf;

@end

@implementation ViewController

- (UITextField *)tf {
    if (!_tf) {
        _tf = [[UITextField alloc] initWithFrame:CGRectMake(50, 100, 200, 40)];
        _tf.borderStyle = UITextBorderStyleRoundedRect;
        [self.view addSubview:_tf];
    }
    return _tf;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    //RAC实时监听输入框的值
    [self.tf.rac_textSignal subscribeNext:^(NSString * _Nullable x) {
        NSLog(@"%@",x);
    }];

@end

控制台打印结果

2018-04-21 18:44:11.775392+0800 RAC常见用法[47518:1991465] 1
2018-04-21 18:44:12.069070+0800 RAC常见用法[47518:1991465] 12
2018-04-21 18:44:12.589818+0800 RAC常见用法[47518:1991465] 123
2018-04-21 18:44:12.784590+0800 RAC常见用法[47518:1991465] 1233
2018-04-21 18:44:12.992636+0800 RAC常见用法[47518:1991465] 12331
2018-04-21 18:44:13.116296+0800 RAC常见用法[47518:1991465] 123314
2018-04-21 18:44:13.302748+0800 RAC常见用法[47518:1991465] 1233141
2018-04-21 18:44:14.850617+0800 RAC常见用法[47518:1991465] 123314
2018-04-21 18:44:15.113347+0800 RAC常见用法[47518:1991465] 12331
2018-04-21 18:44:15.270610+0800 RAC常见用法[47518:1991465] 1233
2018-04-21 18:44:15.422058+0800 RAC常见用法[47518:1991465] 12336
2018-04-21 18:44:15.579953+0800 RAC常见用法[47518:1991465] 123366
2018-04-21 18:44:15.746990+0800 RAC常见用法[47518:1991465] 1233666

联系我:
qq: 1245424073
微信: liujunmin6980

相关文章

网友评论

      本文标题:RAC框架源码解析之常见用法

      本文链接:https://www.haomeiwen.com/subject/mpixlftx.html