使用ReactiveCocoa时未调用错误块

时间:2013-11-08 00:57:56

标签: ios objective-c reactive-cocoa

出于某种原因,我没有收到错误消息。 (我在这里简化了代码以直截了当。)

// Send an error message 
_loginButton.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber sendError:error]; // Pretend this is a real error
        return nil;
    }];
}];

// Subscribe to loginButton's returned signal
[_loginButton.rac_command.executionSignals subscribeNext:^(RACSignal *loginSignal) {
    [loginSignal subscribeError:^(NSError *error) {
         NSLog(@"A");
    } completed:^{
         NSLog(@"B");
    }];
}];

打印“B”。知道为什么吗?如果在订户上调用-sendError:,为什么完成块会收到它?

2 个答案:

答案 0 :(得分:7)

基于this suggestion,这似乎有效(实现它并取消实现)。

// Send an error message 
_loginButton.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
    return [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber sendError:error]; // Pretend this is a real error
        return nil;
    }] materialize];
}];

// Subscribe to loginButton's returned signal
[_loginButton.rac_command.executionSignals subscribeNext:^(RACSignal *loginSignal) {
    [[loginSignal dematerialize] subscribeError:^(NSError *error) {
         NSLog(@"A");
    } completed:^{
         NSLog(@"B");
    }];
}];

答案 1 :(得分:7)

正如您所发现的那样,RACCommand会自动捕获executionSignals内的错误。

这旨在为-flatten-concat-switchToLatest等运营商带来便利,如果任何内部信号发生错误,这些运营商会过早终止。

如果你关心的只是知道何时发生错误,你应该使用RACCommand.errors代替。如果您想知道错误发生的位置,那么检查错误域和代码可能比订阅每个内部信号的error事件更容易(或至少更直观)。

订阅内订阅,甚至subscriptions in general,在RAC中都有代码味道。即使您不想使用errors,通常也会有更高级别的运算符来完成您想要的操作(例如使用-map:-catch:应用于每个内部信号。)< / p>