zoukankan      html  css  js  c++  java
  • ReactiveObjC(RAC)的使用汇总

    RAC 指的就是 RactiveCocoa ,是 Github 的一个开源框架,能够帮我们提供大量方便的事件处理方案,让我们更简单粗暴地去处理事件,现在分为 ReactiveObjCReactiveSwift ,两个框架的功能使用相似,由于正好在学习这个然后公司项目是用 OC 写的,所以将 ReactiveObjC 的使用方法记录一下。

    ReactiveObjC 的使用

    RAC 的核心思想:创建信号 - 订阅信号 - 发送信号 ,并且在 RAC 中我们会看到大量的 block ,所以在使用之前可以再重新温习一下 block 的使用。

    1. RACSignal 信号

    /* 创建信号 */
    RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        /* 发送信号 */
        [subscriber sendNext:@"发送信号"];
        
        return nil;
    }];
    
    /* 订阅信号 */
    RACDisposable *disposable = [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"信号内容:%@", x);
    }];
    
    /* 取消订阅 */
    [disposable dispose];

    2. RACSubject 信号

    和代理的用法类似,通常用来代替代理,有了它,就不必要定义代理了。

    /* 创建信号 */
    RACSubject *subject = [RACSubject subject];
    
    /* 发送信号 */
    [subject sendNext:@"发送信号"];
    
    /* 订阅信号(通常在别的视图控制器中订阅,与代理的用法类似) */
    [subject subscribeNext:^(id  _Nullable x) {
        
        NSLog(@"信号内容:%@", x);
    }];

    3. RACTuple 元祖

    RAC 的元祖,跟我们 OC 的数组其实是一样的,它其实就是封装了我们 OC 的数组。

    /* 创建元祖 */
    RACTuple *tuple = [RACTuple tupleWithObjects:@"1", @"2", @"3", @"4", @"5", nil];
    
    /* 从别的数组中获取内容 */
    RACTuple *tuple = [RACTuple tupleWithObjectsFromArray:@[@"1", @"2", @"3", @"4", @"5"]];
    
    /* 利用 RAC 宏快速封装 */
    RACTuple *tuple = RACTuplePack(@"1", @"2", @"3", @"4", @"5");
    
    NSLog(@"取元祖内容:%@", tuple[0]);
    NSLog(@"第一个元素:%@", [tuple first]);
    NSLog(@"最后一个元素:%@", [tuple last]);

    4. 便利 Array 数组和 Dictionary 字典

    可以省去使用 for 循环来遍历。

    /* 遍历数组 */
    NSArray *array = @[@"1", @"2", @"3", @"4", @"5"];
    [array.rac_sequence.signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"数组内容:%@", x); // x 可以是任何对象
    }];
    /* 遍历字典 */
    NSDictionary *dictionary = @{@"key1":@"value1", @"key2":@"value2", @"key3":@"value3"};
    [dictionary.rac_sequence.signal subscribeNext:^(RACTuple * _Nullable x) {
        RACTupleUnpack(NSString *key, NSString *value) = x; // x 是一个元祖,这个宏能够将 key 和 value 拆开
        NSLog(@"字典内容:%@:%@", key, value);
    }];

    下面两个方法都是将数组内容全部换为 0 ,第一个是单个操作,,第二个是一次性全部替换,两个方法都不会改变原数组内容,操作完后都会生成一个新的数组,省去了创建可变数组然后遍历出来单个添加的步骤。

    /* 内容操作 */
    NSArray *array = @[@"1", @"2", @"3", @"4", @"5"];
    NSArray *newArray = [[array.rac_sequence map:^id _Nullable(id  _Nullable value) {
        NSLog(@"数组内容:%@", value);
        return @"0"; // 将所有内容替换为 0
    }] array];
    /* 内容快速替换 */
    NSArray *array = @[@"1", @"2", @"3", @"4", @"5"];
    NSArray *newArray = [[array.rac_sequence mapReplace:@"0"] array]; // 将所有内容替换为 0

    5. 监听 TextField 的输入改变

    可以省去设置 delegate 和实现代理方法的步骤。

    /* 监听 TextField 的输入(内容改变就会调用) */
    [[textField rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
        NSLog(@"输入框内容:%@", x);
    }];
    /* 添加监听条件 */
    [[textField.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
        return value.length > 5; // 表示输入文字长度 > 5 时才会调用下面的 block
    }] subscribeNext:^(NSString * _Nullable x) {
         NSLog(@"输入框内容:%@", x);
    }];

    6. 监听 Button 点击事件

    可以省去 addTarget 添加事件和创建方法的步骤。

    [[button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
        NSLog(@"%@ 按钮被点击了", x); // x 是 button 按钮对象
    }];

    7. 登录按钮状态实时监听

    下面表示只有 用户名密码 输入框内容都大于 0 时,登录 按钮才可以点击,而且状态是实时监听的,一句代码就能完成这个功能。

    RAC(_loginButton, enabled) = [RACSignal combineLatest:@[_username.rac_textSignal, _password.rac_textSignal] reduce:^id _Nullable(NSString * username, NSString * password){
        return @(username.length && password.length);
    }];

    8. 监听 Notification 通知事件

    可省去在 -(void)dealloc {} 中清除通知和监听通知创建方法的步骤。

    [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardDidShowNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) {
        NSLog(@"%@ 键盘弹起", x); // x 是通知对象
    }];

    9. 代替 Delegate 代理方法

    可以省去监听以及设置 delegate 的步骤,下面表示只要 view 中执行了 btnClick 这个方法,就会发送信号执行这个回调。

    [[view rac_signalForSelector:@selector(btnClick)] subscribeNext:^(RACTuple * _Nullable x) {
        NSLog(@" view 中的按钮被点击了");
    }];

    10. 代替 KVO 监听

    可以代替 KVO 监听,下面表示把监听 viewframe 属性改变转换成信号,只要值改变就会发送信号。

    [[view rac_valuesForKeyPath:@"frame" observer:self] subscribeNext:^(id  _Nullable x) {
        NSLog(@"属性的改变:%@", x); // x 是监听属性的改变结果
    }];

    还有一种更简单的写法,就是利用 RAC 的宏,和上面的效果是一样的。

    [RACObserve(view, frame) subscribeNext:^(id  _Nullable x) {
        NSLog(@"属性的改变:%@", x); // x 是监听属性的改变结果
    }];

    11. 代替 NSTimer 计时器

    可以代替 NSTimer 使用。

    @interface ViewController ()
    
    @property (nonatomic, strong) RACDisposable *disposable;
    
    @end
    /* 定义计时器监听 */
    self.disposable = [[RACSignal interval:1.0 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(NSDate * _Nullable x) {
        NSLog(@"当前时间:%@", x); // x 是当前的系统时间
        
        /* 关闭计时器 */
        [_disposable dispose];
    }];

    作者:Jonzzs
    链接:https://www.jianshu.com/p/0845b1a07bfa
    来源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
  • 相关阅读:
    算法训练 P1103
    算法训练 表达式计算
    算法训练 表达式计算
    基础练习 时间转换
    基础练习 字符串对比
    Codeforces 527D Clique Problem
    Codeforces 527C Glass Carving
    Codeforces 527B Error Correct System
    Codeforces 527A Glass Carving
    Topcoder SRM 655 DIV1 250 CountryGroupHard
  • 原文地址:https://www.cnblogs.com/xujinzhong/p/11352223.html
Copyright © 2011-2022 走看看