为什么RACCommand的块返回信号?

Ash*_*row 26 objective-c reactive-programming ios reactive-cocoa

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

我理解RACCommand它的canExecute信号和信号块的用例,以及如何将它连接到UI元素.但是,返回其他东西会有什么情况[RACSignal empty]呢?

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

    return [RACSignal empty];
}];
Run Code Online (Sandbox Code Playgroud)

Dav*_*Lee 28

每条规则都有例外,但通常您希望所有" // Do stuff"都由返回的信号捕获.换句话说,你的例子会更好:

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

        return [RACSignal empty];
    }];
}];
Run Code Online (Sandbox Code Playgroud)

这种变化的直接好处是,在" // Do stuff" 的持续时间内,您infoButton将被禁用,防止在返回的信号完成之前点击/点击它.在您的原始代码中,"do stuff"在信号之外,因此您的按钮不会被正确禁用.

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

  • 是的,绝对的.一个示例是,如果按钮用于协调与某些API的交互,您可以订阅结果信号以获取该API调用的结果. (2认同)

Nik*_*nov 7

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

RAC(self, items) = [loadItems.executionSignals switchToLatest];
Run Code Online (Sandbox Code Playgroud)

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

[self rac_liftSelector:@selector(displayError:) 
           withSignals:loadItems.errors, nil];
Run Code Online (Sandbox Code Playgroud)

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


ter*_*wis 6

我有一个可能有帮助的例子,尽管其他人可能能够更好地解释它. RACCommand示例

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