特别注意:定义的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<RACSubscriber> 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
被抛出://4
,completed
也被抛出了//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<RACSubscriber> 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:^{}];
}];
}];
网友评论