我在 Reactive Cocoa 中遇到了一些非常简单的代码问题,我不明白我做错了什么。
我只是试图将 UIButton 的启用状态绑定(bind)到信号。该信号采用 UITextField
的文本并通过正则表达式运行它。这样我就可以在正则表达式匹配时启用按钮。
这段代码在加载 View Controller 时给了我一个异常:
// Poperties used in the view controller
@property (strong, nonatomic) NSRegularExpression *regex;
@property (weak, nonatomic) IBOutlet UITextField *myTextField;
@property (weak, nonatomic) IBOutlet UIButton *continueButton;
// ... other stuff ...
// Code in my "view did load" method
RACSignal *mySignal = RACObserve(self, myTextField);
[mySignal deliverOn:[RACScheduler mainThreadScheduler]];
@weakify(self);
[mySignal map:^(NSString *value) {
@strongify(self);
NSUInteger matches = [self.regex numberOfMatchesInString:value
options:0
range:NSMakeRange(0, [value length])];
return @(matches > 0);
}];
RAC(self.continueButton, enabled) = mySignal;
很明显,异常说明我正在尝试从 UITextField
中“启用”选择器,而 UITextField
没有此选择器。我不明白为什么当我在 continueButton
而不是 myTextField
中调用启用的选择器时会出现此错误。
基本上异常(exception)是:
[UITextField charValue]: unrecognized selector sent to instance 0xa2c7830
调试器停在该行:
[object setValue:x ?: nilValue forKeyPath:keyPath];
实例 0xa2c7830
是一个 UITextField
。 object
是 UIButton
而 keyPath
是 @"enabled"
。我只是看不出这个设置有什么问题,除了它是在我的 UITextField
而不是 UIButton
上调用的!
感谢您的帮助!
提示在这里:
[UITextField charValue]
无法识别的选择器未启用
;它是 charValue
。好的,为什么我们要让 UITextField
变成 char
?嗯...如果我们想将其转换为 bool 值,那么 KVO 机制可能会认为它是一个 NSNumber
并尝试将其视为这样。但它不是 NSNumber
- 因此是异常(exception)。
但是等等,我们不是将信号映射为创建一个 NSNumber
吗?为什么我们首先要尝试将其转换为 bool 值?为什么它是 UITextField
而不是 NSString
? (我们稍后再讨论)
啊。好吧,我们实际上并没有将信号映射到其他东西,因为 map:
没有破坏性。
我的意思是 map:
创建一个新信号。它不会修改 mySignal
。我们调用 map:
来创建一个新信号,但是我们从来没有对它做任何事情——它只是坐在那里,没有人订阅它,然后它就被释放了。但我们想订阅它!
RAC(self.continueButton, enabled) = [mySignal map:^(NSString *value) {
@strongify(self);
NSUInteger matches = [self.regex numberOfMatchesInString:value
options:0
range:NSMakeRange(0, [value length])];
return @(matches > 0);
}];
啊哈!现在我们将 enabled
属性绑定(bind)到转换后的信号——这正是我们一直想要的。但还是有些不对劲。
当我们尝试进行正则表达式匹配时会发生一些不好的事情......如果我不得不猜测 [UITextField length]: unrecognized selector sent to instance 0xWhatever
UITextField
再次?那家伙怎么了?
这个问题的答案回到 mySignal
。 mySignal
实际上 发送什么?我们希望它发送文本...但如果我刚刚编写的新异常是正确的,它会发送一个 UITextField
!为什么?那么,mySignal
是 RACObserve(self, myTextField)
。可是等等!这将发送文本字段的新值——而不是文本字段文本的新值。你想要的是:
RACSignal *mySignal = self.myTextField.rac_textSignal;
这将发送文本字段文本的新值,而不是文本字段的新值。
呸。那应该行得通。提示:log*
帮助器对于调试非常有用。
RAC(self.continueButton, enabled) = [mySignal logAll];
这会告诉你 mySignal
正在发送 UITextField
s 而不是 NSString
s。
关于ios - 基于 UITextField 中文本的响应式(Reactive) Cocoa 启用按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22845419/
欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) | Powered by Discuz! X3.4 |