iOS RAC - RACCommand
文章系列
《RACSignal 》
《RACDisposable》
《RACSubject、RACReplaySubject》
《iOS RAC - 基本用法》
《iOS RAC - 定时器》
《iOS RAC - RACMulticastConnection》
《iOS RAC - RACCommand》
《iOS RAC - 核心方法bind》
《iOS RAC - 集合RACTuple、RACSequence》
《iOS RAC - rac_leftSelector》
《iOS RAC - 映射》
《iOS RAC - 过滤》
《iOS RAC - 登录页面,MVVM》
Command翻译过来就是命令,RACCommand是用来干啥子的呢?我们来简单的看看。
RACCommand * command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
return nil;
}];
[command execute:@"开始飞起来"];
然后就愉快的运行了,然后就是愉快的奔溃了。然后我们查看一下奔溃日志
![](https://img.haomeiwen.com/i1940927/b989545321c5ec58.png)
在log中很明确的告诉我们,返回的信号不能为空,既然如此我们就放回一个信号给他呗。
于是代码变成了这样子的:
RACCommand * command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
return nil;
}];
}];
再次愉快的运行,这次没有奔溃,啥都没有,那我们发送的数据呢?[command execute:@"开始飞起来"];
没错就是在创建command的block中的input参数
我们可以打印一下
![](https://img.haomeiwen.com/i1940927/c4d61384df8c7837.png)
既然返回的是一个信号,那我们就尝试着发布信息
RACCommand * command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
NSLog(@"%@",input);
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@"大佬大佬放过我"];
return nil;
}];
}];
这个时候问题来了,发送的信息谁去接收呢???
这个时候我们注意一下execute
这个方法
![](https://img.haomeiwen.com/i1940927/3451d8f32c4eddbe.png)
把代码改成这个样子,大胆的猜测一下,在创建的方法中返回的信号就是他
RACSignal * signal = [command execute:@"开始飞起来"];
[signal subscribeNext:^(id _Nullable x) {
NSLog(@"接收数据 - %@",x);
}];
运行查看结果
![](https://img.haomeiwen.com/i1940927/21a5df30ca175edd.png)
还有没有别的方法可以拿到呢?肯定有啦,不然就打这行字啦
[command.executionSignals subscribeNext:^(id _Nullable x) {
NSLog(@"接收数据 - %@",x);
}];
通过这个也可以获取到数据,executionSignals就是用来发送信号的信号源,需要注意的是这个方法一定要在执行execute
方法之前,否则就不起作用了,然后就运行程序发现,给我的竟然是一个信号????黑人问号??
![](https://img.haomeiwen.com/i1940927/d0bec8fc6bed1280.png)
事已至此,既然是信号我们就在订阅一次吧,看看会拿到什么值。
![](https://img.haomeiwen.com/i1940927/3d93145182691c51.png)
好吧,一波三折终于拿到了值,现在我们要去看看execute
这个方法里面到底做了什么骚操作,不然心有不甘啊……
![](https://img.haomeiwen.com/i1940927/1c84e0a73803440a.png)
就是这个家伙我们才可以先发送后订阅啊
上面的操作是不是很繁琐?没关系,RAC肯定给了你更好的骚操作
除了上面那个双层订阅,我们还可以用这个switchToLatest
![](https://img.haomeiwen.com/i1940927/c9ef06e4d0a0331d.png)
其中switchToLatest
表示的是最新发送的信号,验证一下看他是不是最新的信号吧。
1、先创建5个RACSubject,其中第一个为信号中的信号(也就是发送的数据是信号)
RACSubject *signalofsignal = [RACSubject subject];
RACSubject *signal1 = [RACSubject subject];
RACSubject *signal2 = [RACSubject subject];
RACSubject *signal3 = [RACSubject subject];
RACSubject *signal4 = [RACSubject subject];
2、然后我们就订阅信号中的信号(因为我们约定了,发送的是信号,所以接收到的也是信号,既然是信号,那就可以订阅)
[signalofsignal subscribeNext:^(id _Nullable x) {
[x subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
}];
3、发送数据
[signalofsignal sendNext:signal1];
[signal1 sendNext:@"1"];
现在我们查看log吧
![](https://img.haomeiwen.com/i1940927/afea02c72813f4c3.png)
现在我们在用switchToLatest
在去订阅看看
![](https://img.haomeiwen.com/i1940927/72fbefcc14a29bfb.png)
可以看到一样可以拿到数据,现在我们开始测试发送多个信号,看拿到是不是最后一个信号
![](https://img.haomeiwen.com/i1940927/00e1d2bac2d7dbeb.png)
OK,会到command中,我们现在已经验证了之前的推测,现在如果想监听到执行完成或者还在执行就可以这样子
![](https://img.haomeiwen.com/i1940927/f7cbfbb9f1b6edf0.png)
在上面的过程中,我们发现有两点不太对:
- 1、刚运行的时候就来了一次执行结束,这个不是我们想要的
- 2、并没有结束,但其实我们已经完成了
我们先解决第2个问题,在command的block我们可以注意到,我们在signal的block中只发送了数据,并没有告诉外界发送完成了,所以就导致了,一直没发送完成,所以我们在发送数据之后加上[subscriber sendCompleted];
![](https://img.haomeiwen.com/i1940927/8c6836c485ce54a0.png)
然后我们在来看第1个问题,为什么第一次就执行结束了,这次的判断不是我们想要的, 那我们可不可以跳过呢?
答案肯定是可以的啦
这个时候我需要用到一个方法skip
,这个方法后面有一个参数,填的就是忽略的次数,我们这个时候只想忽略第一次, 所以就填1
[[command.executing skip:1] subscribeNext:^(NSNumber * _Nullable x) {
if ([x boolValue]) {
NSLog(@"还在执行");
}else{
NSLog(@"执行结束了");
}
}];
这个时候我们在运行,然后看log
![](https://img.haomeiwen.com/i1940927/fece5a0d81397a43.png)
既然提到了skip
那就随便可以提提其它的类似的方法
filter
过滤某些
ignore
忽略某些值
startWith
从哪里开始
skip
跳过(忽略)次数
take
取几次值 正序
takeLast
取几次值 倒序