使用KVO时获得异常

时间:2010-11-01 07:43:10

标签: cocoa mkmapview key-value-observing

我正在实现基于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>

3 个答案:

答案 0 :(得分:3)

  

它的工作是例外,但有时候会出现异常'EXC_BAD_ACCESS'。我的日志如下,它显示我泄漏的内存。 ...

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

这与泄漏相反。 被解除分配;泄漏是指对象永远不会解除分配。

问题在于,当其他东西仍然在观察它时,它会被解除分配。任何仍在观察此对象的东西也可能在以后发送其他消息;当它发生时,这些消息将转到一个死对象(导致你看到的崩溃,发生在该消息之后)或另一个对象。

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

我知道它已经很老但我看到这个代码在stackoverflow和其他存储库中使用了很多,这里是问题的解决方案。

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

MyMapViewController <MKMapViewDelegate> {
NSMutableArray *annot;

}

在viewDidLoad和- (MKAnnotationView *) mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>) annotation 中对其进行初始化 你应该在annView addObserver代码之前将MKAnnotationView添加到mutable数组中:

 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];