使用 KVO 时出现异常

发布于 2024-09-29 16:18:11 字数 867 浏览 7 评论 0原文

我正在实现基于 MKMapView 的应用程序。当我们点击图钉时,我正在使用观察者。观察者的代码如下,

[annView  addObserver:self
       forKeyPath:@"selected" 
       options:NSKeyValueObservingOptionNew
       context:@"ANSELECTED"];

它按预期工作,但有时会出现异常“EXC_BAD_ACCESS”。我的日志如下,它显示内存泄漏。我需要释放服务器吗?如果我?那我应该在哪里发布这个呢?

An instance 0x1b21f0 of class MKAnnotationView is being deallocated
while key value observers are still registered with it. Observation
info is being leaked, and may even become mistakenly attached to
some other object. Set a breakpoint on NSKVODeallocateBreak to stop
here in the debugger. Here's the current observation info:

<NSKeyValueObservationInfo 0x11e5f0> (
<NSKeyValueObservance 0x1b1da0: Observer: 0x120f70, Key path: selected, Options: <New: YES, Old: NO, Prior: NO> Context: 0x2b588, Property: 0x1acaa0>

I am implementing MKMapView based application. In that I am using an observer when we tap on a pin. the observer is code is follows,

[annView  addObserver:self
       forKeyPath:@"selected" 
       options:NSKeyValueObservingOptionNew
       context:@"ANSELECTED"];

It is working as expected, but some time it is getting exception 'EXC_BAD_ACCESS'. My log is as follows and it is showing me a leaking memory. Do I need to release the server?. If I ? then where should I release this?

An instance 0x1b21f0 of class MKAnnotationView is being deallocated
while key value observers are still registered with it. Observation
info is being leaked, and may even become mistakenly attached to
some other object. Set a breakpoint on NSKVODeallocateBreak to stop
here in the debugger. Here's the current observation info:

<NSKeyValueObservationInfo 0x11e5f0> (
<NSKeyValueObservance 0x1b1da0: Observer: 0x120f70, Key path: selected, Options: <New: YES, Old: NO, Prior: NO> Context: 0x2b588, Property: 0x1acaa0>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(3

后eg是否自 2024-10-06 16:18:11

它工作正常,但有时会出现异常“EXC_BAD_ACCESS”。我的日志如下,它显示内存泄漏。 ...

MKAnnotationView 类的实例 0x1b21f0 正在被释放,而键值观察者仍向其注册。

这与泄漏相反。它正在被释放;泄漏是指对象永远不会被释放。

问题在于它正在被释放,而其他东西仍在观察它。任何仍在观察该对象的对象也可能稍后向其发送其他消息;当它发生时,这些消息将发送到一个死对象(导致您看到的崩溃,发生在该消息之后)或发送到另一个对象。

如果观察 MKAnnotationView 的对象拥有它并释放它,则在释放它之前需要将自己作为观察者删除。如果它不拥有它,它可能应该拥有它。

It is working as excepted, but some time it is getting exception 'EXC_BAD_ACCESS'. My log is as follows and it is showing me a leaking memory. …

An instance 0x1b21f0 of class MKAnnotationView is being deallocated while key value observers are still registered with it.

That's the opposite of a leak. It is being deallocated; a leak is when an object will never be deallocated.

The problem is that it's being deallocated while something else is still observing it. Anything that's still observing this object may also send it other messages later; when it does, those messages will go to a dead object (causing the crash you saw, which happened after that message) or to a different object.

If the object that is observing the MKAnnotationView is owning it and releasing it, it needs to remove itself as an observer before releasing it. If it does not own it, it probably should.

对风讲故事 2024-10-06 16:18:11

在释放注释视图之前,您必须停止观察它:

[annView removeObserver:self forKeyPath:@"selected"];

You have to stop observing the annotation view before you release it:

[annView removeObserver:self forKeyPath:@"selected"];
余厌 2024-10-06 16:18:11

我知道它已经很老了,但我发现这段代码在 stackoverflow 和其他存储库中被大量使用,这里是问题的解决方案。

您应该在视图控制器类中创建一个 NSMutableArray ivar,以便存储对注释视图的引用:

MyMapViewController <MKMapViewDelegate> {
NSMutableArray *annot;

}

在 vi​​ewDidLoad 和 - (MKAnnotationView *) mapView:(MKMapView *)theMapView viewForAnnotation:(id 中初始化它) 注释

您应该将 MKAnnotationView 添加到可变数组本身,就在 annView addObserver 代码之前:

 if(nil == annView) {
    annView = [[MyAnnotationView alloc] initWithAnnotation:myAnnotation reuseIdentifier:identifier];
    [annot addObject:annView];
}


[annView addObserver:self
          forKeyPath:@"selected"
             options:NSKeyValueObservingOptionNew
             context:(__bridge void *)(GMAP_ANNOTATION_SELECTED)];

然后,在您的 viewDidDisappear 方法中,您可以迭代该数组并手动删除所有观察者:

    //remove observers from annotation
for (MKAnnotationView *anView in annot){
    [anView removeObserver:self forKeyPath:@"selected"];
}

[annot removeAllObjects];

[super viewDidDisappear:animated];

I know that it's quite old but I see that this code is used a lot on stackoverflow and in other repositories, and here is a solution to the problem.

You should create an NSMutableArray ivar in your view controller class in order to store a reference to your annotations view:

MyMapViewController <MKMapViewDelegate> {
NSMutableArray *annot;

}

Initialize it in your viewDidLoad and in your - (MKAnnotationView *) mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>) annotation

you should add the MKAnnotationView to the mutable array itself right before the annView addObserver code:

 if(nil == annView) {
    annView = [[MyAnnotationView alloc] initWithAnnotation:myAnnotation reuseIdentifier:identifier];
    [annot addObject:annView];
}


[annView addObserver:self
          forKeyPath:@"selected"
             options:NSKeyValueObservingOptionNew
             context:(__bridge void *)(GMAP_ANNOTATION_SELECTED)];

Then, in your viewDidDisappear method you can iterate the array and remove manually all the observers:

    //remove observers from annotation
for (MKAnnotationView *anView in annot){
    [anView removeObserver:self forKeyPath:@"selected"];
}

[annot removeAllObjects];

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