26

我一直在学习很多关于ReactiveCocoa的知识,但有一件事仍然让我感到困惑:为什么信号块RACCommand本身会返回一个信号?

我了解 的用例RACCommand、它的canExecute信号和信号块,以及它如何连接到 UI 元素。但是除了 之外,还有什么情况会返回[RACSignal empty]

infoButton.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
    // Do stuff

    return [RACSignal empty];
}];
4

4 回答 4

28

每个规则都有例外,但通常您希望所有“ // Do stuff”都被返回的信号捕获。换句话说,你的例子会更好:

infoButton.rac_command = [[RACCommand alloc] initWithSignalBlock:^(id input) {
    return [RACSignal defer:^{
        // Do stuff

        return [RACSignal empty];
    }];
}];

此更改的直接好处是,在“ // Do stuff”期间,您infoButton将被禁用,防止它被单击/点击,直到返回的信号完成。在您的原始代码中,“do stuff”在信号之外,因此您的按钮不会被正确禁用。

对于没有太多延迟的工作,例如响应按钮点击而更改 UI,那么启用/禁用的功能RACCommand不会给你带来太多好处。但是,如果工作是网络请求或其他一些可能长时间运行的工作(例如媒体处理),那么您肯定希望在信号中捕获所有这些工作。

于 2013-10-18T04:28:08.057 回答
7

想象一下,您有一个命令应该从网络加载项目列表。您可以在信号块中使用副作用或返回实际发送这些项目的信号。在后一种情况下,您可以执行以下操作:

RAC(self, items) = [loadItems.executionSignals switchToLatest];

此外,信号发送的所有错误都将被重定向到errors信号,因此:

[self rac_liftSelector:@selector(displayError:) 
           withSignals:loadItems.errors, nil];

[RACSignal empty]使用-powered 命令是不可能的。

于 2013-10-18T03:56:49.330 回答
6

我有一个示例可能会有所帮助,尽管其他人可能能够更好地解释它。 RAC 命令示例

但基本上,返回+empty它的方式似乎毫无意义,因为调用命令基本上会使用副作用,这是我们想要避免的。

于 2013-10-18T02:49:37.533 回答
2

而不是使用这个:

infoButton.rac_command = [[RACCommand alloc] initWithSignalBlock:^(id input) {
    return [RACSignal defer:^{
        // Do stuff

        return nil;
    }];
}];

您可以使用此内置方法来控制按钮状态:

- (id)initWithEnabled:(RACSignal *)enabledSignal signalBlock:(RACSignal * (^)(id input))signalBlock;
于 2013-10-21T15:07:50.663 回答