ios - 带有自定义属性 getter 的 KVO 通知

标签 ios objective-c key-value-observing

我正在尝试在 iOS 中收听 UITextView 上的 editable 属性。在 UITextView.h 的 header 中,editable 属性定义为:

@property(nonatomic,getter=isEditable) BOOL editable;

为了监听 KVO 通知,我使用了 addObserver 模式,我将 keyPath 作为 NSStringFromSelector(@selector(isEditable)) 传递,这样如果我正在使用 Xcode 就会警告我未定义的选择器。注册 isEditable 键路径顺利进行,但在更改 TextView 上的 editable 属性后,我从未收到属性更改的通知。我正在注册观察者:

[self.textView addObserver:self
                forKeyPath:NSStringFromSelector(@selector(isEditable))
                   options:NSKeyValueObservingOptionNew
                   context:KVOTestingTestsContext];

但是,如果我改为使用键路径 NSStringFromSelector(@selector(editable)),我确实收到了 KVO 通知,但 Xcode 生成了一个警告,提示我正在使用未声明的选择器“可编辑”。

我想知道是否有更好的模式,如果在应该使用自定义 getter 的情况下出现故障,我应该使用它。或者这是 Xcode/clang 中的错误?

最佳答案

您应该在 addObserverforKeyPath 参数中传递属性的名称,而不是 getter 或 setter:

[self.textView addObserver:self
                forKeyPath:@"editable"
                   options:NSKeyValueObservingOptionNew
                   context:KVOTestingTestsContext];

无需使用 NSStringFromSelector@selector 生成 key 路径。事实上,当您这样做时,您可能会遇到您所面临的问题...

  1. 关键路径基于属性的名称,而不是 getter。这样做的原因是您希望 KVO 拦截 setEditable 方法。如果你将 @"isEditable"(无论它是如何生成的)传递给 addObserver,KVO 将尝试拦截名为 isEditable 的属性的 setter , 而这个属性不存在。

  2. 您使用第二种方法获得通知,因为您最终将 @"editable" 传递给 addObserver,这是您想要做的,但是您正在通过引用不存在的方法(即 editable)来执行此操作,因此会出现编译器警告。

  3. 由于您不能将 getter 或 setter 方法的名称传递给 addObserver,答案是直接使用字符串文字(即 @"editable").

这里有 Apple 的编程指南供引用:Registering for Key-Value Observing

关于ios - 带有自定义属性 getter 的 KVO 通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20013415/

相关文章:

ios - Xcode 中的时间分析器缺少记录设置、显示设置

c# - Apple 在 C# 中推送通知提供程序

ios - Swift 3 需要有关 Realm 查询的帮助

objective-c - 在 objective-c 中将两个音频文件合并为一个

objective-c - 同时以编程方式缩小 NSWindows 数组的规模?

ios - 如何知道 UIButton titlerable.text 是否改变

objective-c - setNeedsDisplay 不起作用?

Cocoa 绑定(bind)到数组中的单个对象

ios - AFNetworking 如何检测是否所有文件都已加载

ios - 如何在后台线程中处理 ARC?