概述
前言
学习 RAC 的过程中,RACCommand
是我一直很迷惑的点,感觉一直抓不到它的要点,不明白为何要这样使用。曾经想过用别的方法来替代,只要能找到替代的方法,暂时就没必要死磕,结果发现避免不了,那就解决他。
实践
RACCommand 最常用于两个地方,监听按钮点击,网络请求
-
按钮点击,使用 RAC 有两种方式
-
UIControl+RACSignalSupport
1- (RACSignal *)rac_signalForControlEvents: (UIControlEvents)controlEvents;
-
UIButton+RACCommandSupport
1@ property (nonatomic, strong) RACCommand *rac_command;
-
-
第一种方式,也是我曾经想过替代
RACCommand
来处理按钮点击事件的方法12345678910111213141516171819202122232425// 按钮是否可点击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<RACSubscriber> subscriber) {/*** 这里可以进行处理按钮点击后的事件,并把想要的结果传递出去*/[subscriber sendNext: @"按钮点击了"];[subscriber sendCompleted];return nil;}];}-
上述就是根据
UIControl
的分类信息,进行处理按钮点击事件的第一种方式。但是有一个问题: -
你只有手动点击了按钮,并且是
UIControlEventTouchUpInside
的事件状态下才会执行 block 中的代码。 - 如果需要主动触发事件呢,而在老代码中,可以手动调用
[self btnClick]
,所以就必须使用第二种方式,RACCommand
。
-
-
RACCommand
-
初始化赋值
rac_command
12345678// 初始化 command, enabled 表示按钮可否点击RACCommand *command = [[RACCommand alloc] initWithEnabled:validSignalsignalBlock:^RACSignal *( id input) {return [ self btnClickSignal];}];self.commandBtn.rac_command = command; -
监听
executionSignals
是信号中的信号- 必须进行处理、转换,得到外层信号
- 监听最外层的信号,才能获取到信号中的信息
12345678910111213141516171819// 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]
12345678// 1. 返回的是 RACSignal,可以被订阅[command execute: nil];// 2. 只有手动 执行命令,才能监听到信号// 如果是 点击按钮, 这里是监听不到信息的[[command execute: nil] subscribeNext:^( id x) {NSLog( @"execute---%@", x);}]; -
executing
是否正在执行命令12345678910// executing 一开始就会监听一次,肯定是 0,一般会忽略(skip)一次// x 非 0 即 1,命令执行完毕/正在执行// 执行一次命令,block 中会调用两次,正在执行->执行完毕[[command.executing skip: 1] subscribeNext:^( id x) {if ([x integerValue] == 1) {NSLog( @"正在执行");} else {NSLog( @"执行完毕");}}];
-
结论
-
上述就是
RACCommand
在按钮点击事件中的处理,网络请求的话,代码几乎一致,流程都是一样的。在初始化RACCommand
的内部,进行事件处理/网络请求,并把结果通过subscriber
发送出去,外部通过订阅信号,就可以获取事件处理的结果,从而进行 UI 更新。 -
RACCommand
本质上就是用来处理事件的,事件如何处理,事件中的数据如何传递,甚至事件的执行过程,都可以表现出来。 -
见识浅薄,如有疑惑,欢迎交流,求吐槽,求成长。
最后
以上就是过时小丸子为你收集整理的RACCommand 粗解的全部内容,希望文章能够帮你解决RACCommand 粗解所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复