我该如何自行注销 KVO?
我尝试使用 KVO 观察 UIView
子类上的属性,以便通过调用 drawRect:
触发绘制。在我的 initWithFrame:
中,我有这个:(
...
self.observedKeysThatTriggerRedraw = [NSArray arrayWithObjects:@"name", nil];
for (NSString *aKey in self.observedKeysThatTriggerRedraw) {
[self observeValueForKeyPath:aKey ofObject:self change:nil context:redrawContextString];
}
...
redrawContextString
是该类独有的常量 NSString
)
KVO 通知按其应有的方式触发,这是正确触发重绘的。问题是取消注册 KVO。如果我不取消注册,一切都会正常运行,但如果我将其放在 dealloc
的顶部,则会出现异常:
for (NSString *aKey in self.observedKeysThatTriggerRedraw) {
[self removeObserver:self forKeyPath:aKey];
}
self.name = nil;
...
[super dealloc];
我在控制台中收到此消息,并且当它到达 <代码>removeObserver:forKeyPath::
CoreAnimation:忽略异常:无法删除观察者
对于来自 的关键路径“name”因为它没有注册为观察者
当你观察self
时,有什么技巧可以注销KVO吗?在调用 dealloc
时,我的观察者是否已取消注册?我在很多地方读到过,你不应该在dealloc中注销KVO,但我不确定在观察self时我还能在哪里做到这一点。
I'm trying to use KVO to observe properties on a UIView
subclass in order to trigger drawing by calling drawRect:
. In my initWithFrame:
, I have this:
...
self.observedKeysThatTriggerRedraw = [NSArray arrayWithObjects:@"name", nil];
for (NSString *aKey in self.observedKeysThatTriggerRedraw) {
[self observeValueForKeyPath:aKey ofObject:self change:nil context:redrawContextString];
}
...
(redrawContextString
is a constant NSString
unique to this class)
The KVO notifications are firing as they should, which is triggering the redraw correctly. The problem is unregistering KVO. If I don't unregister, everything runs fine, but I get an exception if I put this at the top of my dealloc
:
for (NSString *aKey in self.observedKeysThatTriggerRedraw) {
[self removeObserver:self forKeyPath:aKey];
}
self.name = nil;
...
[super dealloc];
I get this message in the console and a crash when it gets to the removeObserver:forKeyPath:
:
CoreAnimation: ignoring exception: Cannot remove an observer <MyViewClass 0x5b47210> for the key path "name" from <MyViewClass 0x5b47210> because it is not registered as an observer
Is there some trick to unregistering KVO when you are observing self
? Are my observers being unregistered for me be the time dealloc
is called? I've read in a bunch of places that you shouldn't unregister for KVO in dealloc
, but I'm not sure where else I can do it when observing self
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您实际上尚未使用
addObserver:forKeypath:options:context:
将视图注册为观察者。您应该将 self 注册为观察者,或者(如果您不以标准方式使用 KVO,则手动发送observeValueForKeyPath...),您不应该尝试取消注册 self 作为观察者。You haven't actually registered the view as an observer with
addObserver:forKeypath:options:context:
. Either you should register self as an observer or (if you don't use KVO in a standard way, manually sendingobserveValueForKeyPath...
), you should not try to unregister self as an observer.