使用ReactiveCocoa时未调用错误块

drh*_*rhr 7 objective-c ios 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");
    }];
}];
Run Code Online (Sandbox Code Playgroud)

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

drh*_*rhr 7

基于这个建议,这似乎有效(实现它并使其非物质化).

// 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");
    }];
}];
Run Code Online (Sandbox Code Playgroud)


Jus*_*ers 7

正如您所发现的,RACCommand自动捕获内部错误executionSignals.

这对于像-flatten,-concat和等操作者来说是方便的,-switchToLatest如果在任何内部信号上发生错误,则会过早地终止.

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

订阅内订阅,甚至订阅,一般都是RAC中的代码味道.即使您不想使用errors,通常也有更高级别的操作符来完成您想要的操作(例如使用-map:应用于-catch:每个内部信号).