Remove the ReactiveCocoa signal from the control

If I assign a signal to the property of the control:

    RAC(self.loginButton.enabled) = [RACSignal
            combineLatest:@[
                    self.usernameTextField.rac_textSignal,
                    self.passwordTextField.rac_textSignal
            ] reduce:^(NSString* username, NSString* password) {
                return @(username.length > 0 && password.length > 0);
            }];

But then it was necessary to assign another RACSignalto enabled, how can I delete all existing ones?

If I try to install it a second time, I get an exception similar to the following:

2013-10-29 16:54:50.623 myApp[3688:c07] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Signal <RACSignal: 0x975e9e0> name: +combineLatest: (
"<RACSignal: 0x975d600> name: <UITextField: 0x10f2c420> -rac_textSignal",
"<RACSignal: 0x975de30> name: <UITextField: 0x10f306e0> -rac_textSignal"
) reduce: is already bound to key path "self.loginButton.enabled" on object <LoginViewController: 0x10f264e0>, adding signal <RACSignal: 0x9763500> name: +combineLatest: (
"<RACSignal: 0x97624f0> name: <UITextField: 0x10f2c420> -rac_textSignal",
"<RACSignal: 0x97629e0> name: <UITextField: 0x10f306e0> -rac_textSignal"
) reduce: is undefined behavior'
+4
source share
2 answers

Most of the ReactiveCocoa philosophy is statefulness. A condition is all that can change over time, and this is problematic for several reasons:

  • You are losing past information. Once a variable has been changed, it, like previous values, never existed.
  • . , , - .
  • Concurrency, , . , , .

, RAC , , . , enabled, ? , ?

, RAC , , . , .

. , - , .

, , , UISwitch:

// A signal that automatically updates with the latest value of
// `self.emailLoginSwitch.on`.
RACSignal *emailLoginEnabled = [[[self.emailLoginSwitch
    rac_signalForControlEvents:UIControlEventValueChanged]
    mapReplace:self.emailLoginSwitch]
    map:^(UISwitch *switch) {
        return @(switch.on);
    }];

// Whether the user has entered a valid username and password.
RACSignal *usernameAndPasswordValid = [RACSignal
    combineLatest:@[
        self.usernameTextField.rac_textSignal,
        self.passwordTextField.rac_textSignal
    ] reduce:^(NSString* username, NSString* password) {
        return @(username.length > 0 && password.length > 0);
    }];

// Whether the user has entered a valid email address.
RACSignal *emailValid = [self.emailTextField.rac_textSignal map:^(NSString *email) {
    return @(email.length > 0);
}];

// Uses different conditions for validity depending (ultimately) on the value of
// `self.emailLoginSwitch`.
RAC(self.loginButton, enabled) = [RACSignal
    if:emailLoginEnabled
    then:emailValid
    else:usernameAndPasswordValid];

, , ( / ), - .

+29

RAC :

[[RACSignal
    combineLatest:@[
       self.usernameTextField.rac_textSignal,
       self.passwordTextField.rac_textSignal
    ] reduce:^(NSString* username, NSString* password) {
       return @(username.length > 0 && password.length > 0);
}] setKeyPath:@"enabled" onObject:self.loginButton nilValue:nil];

< 2.0, -toProperty:onObject:

, , , ReactiveCocoa, , - , :)

0

All Articles