RACCommand 有sendError对executionSignals 怎么破

RACCommand 一般我们都是放在ViewModel中,就像是一个Action,由用户或者View/ViewController的。
而且很多时候,我们不仅仅需要让这个action执行起来,而且还需要知道执行的结果。这里简单写个demo。
@interface ViewModel

  • (RACCommand*)testCommand; @end @implement ViewModel
  • (RACCommand*)testCommand{ return [RACCommand alloc] initWithSignalBlock:^RACSignal *(id input){ return [RACSignal createSignal:^RACDisposable *(id subscriber) { [subscribe sendError:[NSError errorWithDomain:@"" code:0 userInfo:nil]]; }]; //1 }]; @end

如果ViewController中是这么写的。
self.testBtn.rac_command = self.viewModel.testCommand;

现在有这样一个需要,就是知道这个command什么时候被执行了。执行的结果是咋样的,是否有错误,或者完成,那么应该怎么办呢。

之前我是这么写的。

[[self.testBtn.rac_command executing] subscribeNext:^(NSNumber *executing) {
if([executing boolValue]){
NSLog(@"正在执行"); //2
}
}];

[self.testBtn.rac_command.errors subscribeError:^(NSError *error)]{
NSLog(@"发生%@",error); //3
}];

[self.testBtn.rac_command.executionSignals flattenMap:^(RACSignal *exection){
return [[exection ignoreAll] concate:[RACSignal return:RACUnit.defaultUnit]]; //4
} subscribeNext:^(_){
NSLog(@"执行完毕"); //5
}];

感觉没有问题,但是实际的问题来。就是在viewModel中sendError得话,那么3的位置是能够执行到得,但是我不期望的5也被执行了。跟踪之后,发现原来RACCommand里面本身会对error进行catch的然后concate 返回一个error的signal了。所以4中本来应该发现error直接出去的都变成了普通的return signal了。

google一下吧,看看有什么好的解决办法。发现使用materialize 和dematerialize的规避吧。materialize回家所有的信号封装成event的形势出去。这样RACCommand就拿不到error了。也就是说2处也不会有了。只有在需要的地方也就是我们的ViewController中使用dematerialize出来拿到我们实际想要的数据了。

改动不大。在ViewModel中1处成
return [xxxxx materialize];

然后在ViewController中,将3部分代码可以去掉了。executionSignals 的部分需要改成
[self.testBtn.rac_command.executionSignals subscribeNext:^(RACSignal *execution) {
[[[execution dematerialize] deliverOn:[RACScheduler mainThreadScheduler]] subscribeError:^(NSError *error) {
NSLog(@"发生错误");
} completed:^{
NSLog(@"完成");
}];
}];

这样,所有你想要的东西都可以得到了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值