rxswift reactivecocoa ios objective-c reactive-programming reactive-cocoa

ios - reactivecocoa - ¿Por qué el bloque de RACCommand devuelve una señal?



reactivecocoa swift (4)

En lugar de usar esto:

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

Puede utilizar este método incorporado para controlar el estado del botón:

- (id)initWithEnabled:(RACSignal *)enabledSignal signalBlock:(RACSignal * (^)(id input))signalBlock;

He estado aprendiendo mucho sobre ReactiveCocoa pero una cosa todavía me desconcierta: ¿por qué el bloqueo de señal en RACCommand devuelve una señal en sí?

Entiendo los casos de uso de RACCommand , su señal canExecute y el bloque de señal, y cómo se puede conectar a los elementos de la interfaz de usuario. Pero, ¿qué caso habría para devolver algo que no sea [RACSignal empty] ?

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


Hay excepciones a todas las reglas, pero generalmente desea que todas las " // Do stuff " sean capturadas por la señal devuelta. En otras palabras, su ejemplo sería mejor como:

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

El beneficio directo de este cambio es que, durante la duración de " // Do stuff ", su infoButton se deshabilitará, evitando que se infoButton clic / toque hasta que la señal devuelta se haya completado. En su código original, el "hacer cosas" está fuera de la señal, y como tal, su botón no se desactivará correctamente.

Para el trabajo que no tiene mucha latencia, por ejemplo, realizar cambios en la interfaz de usuario en respuesta a un toque de botón, entonces la función habilitada / deshabilitada de RACCommand no le compra mucho. Pero si el trabajo es una solicitud de red, o algún otro trabajo potencialmente de larga ejecución (procesamiento de medios, por ejemplo), entonces definitivamente desea que todo ese trabajo sea capturado dentro de una señal.


Imagina que tienes un comando que debería cargar la lista de elementos de la red. Puede usar efectos secundarios en el bloqueo de la señal o devolver una señal que realmente envíe estos elementos. En este último caso puedes hacer lo siguiente:

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

Además, todos los errores enviados por señal se redireccionarán a la señal de errors , por lo que:

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

Es imposible con los [RACSignal empty] con [RACSignal empty] -powered.


Tengo un ejemplo que podría ser útil, aunque otros podrían explicarlo mejor. Ejemplo RACCommand

Pero básicamente, la forma en que lo tiene con regresar +empty parece algo inútil, ya que invocar el comando básicamente usará efectos secundarios, que queremos evitar.