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;
    }];
}];

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

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

4

2 回答 2

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");
    }];
}];
于 2013-11-08T02:28:37.550 回答
7

正如您所发现的,它会RACCommand自动捕获executionSignals.

这是为了方便, 和等运算符-flatten,否则如果任何内部信号发生错误,它们会过早终止。-concat-switchToLatest

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

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

于 2013-11-08T07:54:30.223 回答