RACCommand响应结果解析

特别注意:定义的command中的封装信号一定要sendCompleted;否则在生命周期内无法被重新激活;

1. 普通的command

普通的RACCommand的使用很简单了,只需要在封装的信号中sendCompleted、sendError就可以。例如:

- (RACCommand *)commandForDataSelecting {
  if (!_commandForDataSelecting) {
    @weakify(self);
    _commandForDataSelecting = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
        return [[RACSignal createSignal:^RACDisposable *(id subscriber) {
            @strongify(self);
            [[DBManager sharedDB] selectDataFromTabel:kCardInfoTableName forConditions:nil sucBlock:^(NSArray *datasSelected) {
                [subscriber sendCompleted];
            } errBlock:^(NSError *error) {
                [subscriber sendError:error];
            }];
            return nil;
        }] replayLast];
    }];
  }
  return _commandForDataSelecting;
}

2. 获取响应状态

要处理的状态有3种:开始,完成,失败

  • 开始

    [[command executing] subscribeNext:^id(id x) {
        NSLog(@"数据加载中...");
    } // 或者在 'subscribeNext' 前面加上 'deliverOn:' 在主线程中处理;
    
  • 完成

    [[[command executionSignals] flattenMap:^ RACStream(RACSignal* innerSignal) {
        return [innerSignal materialize];
    }] subscribeNext:^(RACEvent* event) {
        if (event.eventType == RACEventTypeCompleted) {
            NSLog(@"数据加载完毕!"); // 1
        }
        else if (event.eventType == RACEventTypeError) {
            NSLog(@"数据加载失败!"); //2
        }
        else if (event.eventType == RACEventTypeNext) {
            NSLog(@"数据加载中..."); //3
        }
    }];
    

实际测试发现,subscribeNext只能获取到 completed的状态,所以可以在 subscribeNext 前对结果进行过滤:filter:,过滤出completed的状态。

  • 失败

    [[command errors] subscribeNext:^(NSError* error) {
        NSLog(@"%@",[error localizedDescription]); //4
    }
    

3. 疑惑和解惑

  • command能正常结束时,一切都没问题。可是当command执行异常时,不仅异常errors被抛出://4completed也被抛出了//1
  • 如果上面 // 1-4 都用蒙版 MBProgressHUD 显示的话,线程调度会有问题,蒙版显示会一闪而过;

所以,我们要解决的目标:command 抛出 error 时,不要同时抛出 completed .

  • 解决方法
    command的定义中,将返回的RACSignal再次封装materialize,封装后产生的信号的值是RACEvent类型;
    然后executionSignals通过解封装dematerialize出一个新的信号,对它进行'异常'、'完成'捕获:subscribeError: completed:分别处理异常和完成状态.

新的command定义和executionSignals处理如下:

// command定义
- (RACCommand *)commandForDataSelecting {
  if (!_commandForDataSelecting) {
    @weakify(self);
    _commandForDataSelecting = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
        return [[[[RACSignal createSignal:^RACDisposable *(id subscriber) {
            @strongify(self);
            [[DBManager sharedDB] selectDataFromTabel:kCardInfoTableName forConditions:nil sucBlock:^(NSArray *datasSelected) {
                self.cardInfosSelected = [datasSelected copy];
                [subscriber sendCompleted];
            } errBlock:^(NSError *error) {
                [subscriber sendError:error];
            }];
            return nil;
        }] replayLast] materialize] delay:1];
    }];
  }
  return _commandForDataSelecting;
}

 // 结果处理
 [command.executionSignals subscribeNext:^(RACSignal* signal) {
    @strongify(self);
    [[[signal dematerialize] deliverOn:[RACScheduler mainThreadScheduler]] subscribeError:^(NSError *error) {
        [self.progressHUD showFailWithText:[error localizedDescription] andDetailText:nil onCompletion:nil];
    } completed:^{
        [self.progressHUD showSuccessWithText:@"加载成功" andDetailText:nil onCompletion:^{}];
    }];
}];

你可能感兴趣的:(RACCommand响应结果解析)