I've been learning a lot about ReactiveCocoa but one thing still puzzles me: why does the signal block on RACCommand
return a signal itself?
I understand the use cases of RACCommand
, its canExecute
signal and signal block, and how it can be hooked up to UI elements. But what case would there be ever for returning something other than [RACSignal empty]
?
infoButton.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
// Do stuff
return [RACSignal empty];
}];
There are exceptions to every rule, but generally you want all your "// Do stuff
" to be captured by the returned signal. In other words, your example would be better as:
infoButton.rac_command = [[RACCommand alloc] initWithSignalBlock:^(id input) {
return [RACSignal defer:^{
// Do stuff
return [RACSignal empty];
}];
}];
The direct benefit of this change is that, for the duration of "// Do stuff
", your infoButton
will be disabled, preventing it from being clicked/tapped until the returned signal has completed. In your original code, the "do stuff" is outside of the signal, and as such your button won't be disabled properly.
For work that doesn't have much latency, for example making UI changes in response to a button tap, then the enabled/disabled feature of RACCommand
doesn't buy you much. But if the work is a network request, or some other potentially long running work (media processing for example), then you definitely want all of that work captured within a signal.
Imagine you have a command that should load list of items from network. You could use side effects in signal block or return a signal that would actually send these items. In the latter case you can do the following:
RAC(self, items) = [loadItems.executionSignals switchToLatest];
Also all errors sent by signal would be redirected to errors
signal, so:
[self rac_liftSelector:@selector(displayError:)
withSignals:loadItems.errors, nil];
It's impossible with [RACSignal empty]
-powered commands.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With