我该如何自行注销 KVO?

发布于 2024-10-15 14:25:25 字数 1133 浏览 2 评论 0原文

我尝试使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

久隐师 2024-10-22 14:25:25

您实际上尚未使用 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 sending observeValueForKeyPath...), you should not try to unregister self as an observer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文