博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
RACCommand 粗解
阅读量:6548 次
发布时间:2019-06-24

本文共 2970 字,大约阅读时间需要 9 分钟。

前言

学习 RAC 的过程中,RACCommand 是我一直很迷惑的点,感觉一直抓不到它的要点,不明白为何要这样使用。曾经想过用别的方法来替代,只要能找到替代的方法,暂时就没必要死磕,结果发现避免不了,那就解决他。

实践

RACCommand 最常用于两个地方,监听按钮点击,网络请求

  1. 按钮点击,使用 RAC 有两种方式

    • UIControl+RACSignalSupport
    - (RACSignal *)rac_signalForControlEvents:(UIControlEvents)controlEvents;复制代码
    • UIButton+RACCommandSupport
    @property (nonatomic, strong) RACCommand *rac_command;复制代码
  2. 第一种方式,也是我曾经想过替代 RACCommand 来处理按钮点击事件的方法

    // 按钮是否可点击RAC(self.commandBtn, enabled) = validSignal;[[[self.commandBtn rac_signalForControlEvents:UIControlEventTouchUpInside]  // flattenMap 生成新的信号,在信号中可以处理点击事件,并发送结果   flattenMap:^RACStream *(id value) {       return [self btnClickSignal];   }] subscribeNext:^(id x) {       NSLog(@"====%@", x); // ====按钮点击了   }];   - (RACSignal *)btnClickSignal {    return [RACSignal createSignal:^RACDisposable *(id
    subscriber) { /** * 这里可以进行处理按钮点击后的事件,并把想要的结果传递出去 */ [subscriber sendNext:@"按钮点击了"]; [subscriber sendCompleted]; return nil; }];}复制代码
    • 上述就是根据 UIControl 的分类信息,进行处理按钮点击事件的第一种方式。但是有一个问题:

    • 你只有手动点击了按钮,并且是 UIControlEventTouchUpInside 的事件状态下才会执行 block 中的代码。

    • 如果需要主动触发事件呢,而在老代码中,可以手动调用 [self btnClick],所以就必须使用第二种方式,RACCommand

  3. RACCommand

    • 初始化赋值 rac_command
    // 初始化 command, enabled 表示按钮可否点击RACCommand *command = [[RACCommand alloc] initWithEnabled:validSignal                                              signalBlock:^RACSignal *(id input) {                                                                                                 return [self btnClickSignal];                                                                                              }];self.commandBtn.rac_command = command;复制代码
    • 监听
      • executionSignals 是信号中的信号
      • 必须进行处理、转换,得到外层信号
      • 监听最外层的信号,才能获取到信号中的信息
    // 1. 监听信号中的信号[command.executionSignals subscribeNext:^(id x) {    [x subscribeNext:^(id x) {        NSLog(@"---%@", x);    }];    }];// 2. 使用 flattenMap 进行转换,返回最外层的信号[[command.executionSignals flattenMap:^RACStream *(id value) {   return value;}] subscribeNext:^(id x) {   NSLog(@"---%@", x); }];// 3. switchToLatest 获取最新的信号,专门用于处理 信号中的信号[command.executionSignals.switchToLatest subscribeNext:^(id x) {    NSLog(@"---%@", x);}];复制代码
    • execute 执行
      • 这也就是解决第一种方式无法主动触发事件方法。
      • 相当于调用 [self btnClick]
    // 1. 返回的是 RACSignal,可以被订阅[command execute:nil];// 2. 只有手动 执行命令,才能监听到信号// 如果是 点击按钮, 这里是监听不到信息的[[command execute:nil] subscribeNext:^(id x) {    NSLog(@"execute---%@", x);}];复制代码
    • executing 是否正在执行命令
    // executing 一开始就会监听一次,肯定是 0,一般会忽略(skip)一次 // x 非 0 即 1,命令执行完毕/正在执行// 执行一次命令,block 中会调用两次,正在执行->执行完毕[[command.executing skip: 1] subscribeNext:^(id x) {   if ([x integerValue] == 1) {       NSLog(@"正在执行");   } else {       NSLog(@"执行完毕");   }    }];复制代码

结论

  1. 上述就是 RACCommand 在按钮点击事件中的处理,网络请求的话,代码几乎一致,流程都是一样的。在初始化 RACCommand 的内部,进行事件处理/网络请求,并把结果通过 subscriber 发送出去,外部通过订阅信号,就可以获取事件处理的结果,从而进行 UI 更新。

  2. RACCommand 本质上就是用来处理事件的,事件如何处理,事件中的数据如何传递,甚至事件的执行过程,都可以表现出来。

  3. 见识浅薄,如有疑惑,欢迎交流,求吐槽,求成长。

转载于:https://juejin.im/post/5a31db5ef265da43333e6979

你可能感兴趣的文章
正确配置jstl的maven依赖,jar包冲突的问题终于解决啦
查看>>
安装 MariaDB
查看>>
C#开发微信门户及应用(5)--用户分组信息管理
查看>>
怎样实现前端裁剪上传图片功能
查看>>
ffmpeg+SDL2实现的视频播放器「退出、暂停、播放」
查看>>
Apriori 关联算法学习
查看>>
JSLint的使用
查看>>
HTTP POST GET 本质区别详解
查看>>
MD5加密
查看>>
ant
查看>>
微信,想要说爱你,却没有那么容易!
查看>>
有关sqlite与sql
查看>>
MapXtreme 2005 学习心得 概述(一)
查看>>
php进一法取整、四舍五入取整、忽略小数等的取整数方法大全
查看>>
WSDP
查看>>
Memory Management
查看>>
JQUERY 对 表格中的数据重排序
查看>>
程序员常用借口指南
查看>>
awk 常用方法
查看>>
Android网络框架实现之【Retrofit+RxJava】
查看>>