我正在尝试在 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 中的错误?
最佳答案
您应该在 addObserver
的 forKeyPath
参数中传递属性的名称,而不是 getter 或 setter:
[self.textView addObserver:self
forKeyPath:@"editable"
options:NSKeyValueObservingOptionNew
context:KVOTestingTestsContext];
无需使用 NSStringFromSelector
和 @selector
生成 key 路径。事实上,当您这样做时,您可能会遇到您所面临的问题...
关键路径基于属性的名称,而不是 getter。这样做的原因是您希望 KVO 拦截
setEditable
方法。如果你将@"isEditable"
(无论它是如何生成的)传递给addObserver
,KVO 将尝试拦截名为isEditable
的属性的 setter , 而这个属性不存在。您使用第二种方法获得通知,因为您最终将
@"editable"
传递给addObserver
,这是您想要做的,但是您正在通过引用不存在的方法(即editable
)来执行此操作,因此会出现编译器警告。由于您不能将 getter 或 setter 方法的名称传递给
addObserver
,答案是直接使用字符串文字(即@"editable"
).
这里有 Apple 的编程指南供引用:Registering for Key-Value Observing
关于ios - 带有自定义属性 getter 的 KVO 通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20013415/