特別注意:定義的command中的封裝信號一定要sendCompleted嚷闭;否則在生命周期內(nèi)無法被重新激活;
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. 獲取響應(yīng)狀態(tài)
要處理的狀態(tài)有3種:開始
,完成
,失敗
-
開始
[[command executing] subscribeNext:^id(id x) { NSLog(@"數(shù)據(jù)加載中..."); } // 或者在 'subscribeNext' 前面加上 'deliverOn:' 在主線程中處理;
-
完成
[[[command executionSignals] flattenMap:^ RACStream(RACSignal* innerSignal) { return [innerSignal materialize]; }] subscribeNext:^(RACEvent* event) { if (event.eventType == RACEventTypeCompleted) { NSLog(@"數(shù)據(jù)加載完畢!"); // 1 } else if (event.eventType == RACEventTypeError) { NSLog(@"數(shù)據(jù)加載失敗!"); //2 } else if (event.eventType == RACEventTypeNext) { NSLog(@"數(shù)據(jù)加載中..."); //3 } }];
實際測試發(fā)現(xiàn)兄裂,subscribeNext
只能獲取到 completed
的狀態(tài),所以可以在 subscribeNext
前對結(jié)果進(jìn)行過濾:filter:
,過濾出completed
的狀態(tài)。
-
失敗
[[command errors] subscribeNext:^(NSError* error) { NSLog(@"%@",[error localizedDescription]); //4 }
3. 疑惑和解惑
- 當(dāng)
command
能正常結(jié)束時晰奖,一切都沒問題谈撒。可是當(dāng)command
執(zhí)行異常時匾南,不僅異常errors
被拋出://4
啃匿,completed
也被拋出了//1
。 - 如果上面
// 1-4
都用蒙版MBProgressHUD
顯示的話蛆楞,線程調(diào)度會有問題溯乒,蒙版顯示會一閃而過;
所以豹爹,我們要解決的目標(biāo):當(dāng) command
拋出 error
時橙数,不要同時拋出 completed
.
-
解決方法
在command
的定義中,將返回的RACSignal
再次封裝materialize
帅戒,封裝后產(chǎn)生的信號的值是RACEvent
類型灯帮;
然后executionSignals
通過解封裝dematerialize
出一個新的信號,對它進(jìn)行'異常'、'完成'捕獲:subscribeError: completed:
分別處理異常和完成狀態(tài).
新的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;
}
// 結(jié)果處理
[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:^{}];
}];
}];