使用基于iOS6.1的MapKit,当我尝试删除所有MKAnnotations然后弹出地图视图控制器时,app会随机崩溃(发生率非常低)。从崩溃日志看,它似乎是一个观察者问题,任何经历过类似问题的人都请给我一些见解,任何想法或讨论都将受到赞赏。提前致谢。
PS:
UIMapView是我应用中的单身人士,只创建一次。
2013-08-13 15:11:59.025 CHSP[9129:c07] CRASH: Cannot remove an observer <MKAnnotationContainerView 0xb8e5120> for the key path "title" from <MKUserLocation 0xbab3440> because it is not registered as an observer.
2013-08-13 15:11:59.060 CHSP[9129:c07] Stack Trace: (
0 CoreFoundation 0x028ff02e __exceptionPreprocess + 206
1 libobjc.A.dylib 0x02030e7e objc_exception_throw + 44
2 CoreFoundation 0x028fedeb +[NSException raise:format:] + 139
3 Foundation 0x01a84a89 -[NSObject(NSKeyValueObserverRegistration) _removeObserver:forProperty:] + 790
4 Foundation 0x01a8471d -[NSObject(NSKeyValueObserverRegistration) removeObserver:forKeyPath:] + 105
5 MapKit 0x009194f9 -[MKAnnotationContainerView _unregisterObserverForBubbleAnnotation:] + 116
6 MapKit 0x00919704 -[MKAnnotationContainerView setBubbleAnnotationView:] + 99
7 MapKit 0x0091925d -[MKAnnotationContainerView _removeBubbleWithAnimation:tellDelegate:] + 247
8 MapKit 0x0091b114 -[MKAnnotationContainerView _deselectAnnotationViewWithAnimation:tellDelegate:] + 128
9 MapKit 0x0091b1e1 -[MKAnnotationContainerView _deselectAnnotationView] + 49
10 MapKit 0x0092198e -[MKAnnotationContainerView _removeAnnotationView:updateCollections:] + 395
11 MapKit 0x009217fe -[MKAnnotationContainerView _removeAnnotationView:] + 48
12 MapKit 0x00921490 -[MKAnnotationContainerView removeAnnotation:] + 375
13 MapKit 0x00921538 -[MKAnnotationContainerView removeAnnotations:] + 160
14 MapKit 0x0090f8bd -[MKMapView removeAnnotations:] + 58
15 CHSP 0x00077fd5 -[UPNewMapViewController removeAllAnnotations] + 101
16 CHSP 0x00076640 -[UPNewMapViewController dealloc] + 64
17 UIKit 0x01055480 -[UIViewController release] + 93
18 libobjc.A.dylib 0x020430c3 objc_release + 51
19 libobjc.A.dylib 0x02043bd9 _ZN12_GLOBAL__N_119AutoreleasePoolPage3popEPv + 555
20 CoreFoundation 0x028a1468 _CFAutoreleasePoolPop + 24
21 CoreFoundation 0x028a5afd __CFRunLoopRun + 1933
22 CoreFoundation 0x028a4f44 CFRunLoopRunSpecific + 276
23 CoreFoundation 0x028a4e1b CFRunLoopRunInMode + 123
24 GraphicsServices 0x02c927e3 GSEventRunModal + 88
25 GraphicsServices 0x02c92668 GSEventRun + 104
26 UIKit 0x00f7753c UIApplicationMain + 1211
27 CHSP 0x0009d9a2 main + 130
28 CHSP 0x00002f55 start + 53
)
2013-08-13 15:11:59.061 CHSP[9129:c07] *** Terminating app due to uncaught exception 'NSRangeException', reason: 'Cannot remove an observer <MKAnnotationContainerView 0xb8e5120> for the key path "title" from <MKUserLocation 0xbab3440> because it is not registered as an observer.'
答案 0 :(得分:0)
由我自己修复。 最初我尝试使用另一个图像来显示用户当前位置而不是Mapkit默认位置,似乎这不是一个好主意。
答案 1 :(得分:0)
我想我发现了实际问题。 我可以按照以下顺序一致地重现问题(即使在iOS 5.1上):
1)让您的应用显示注释+用户位置
2)按主页按钮将应用程序推送到后台
3)禁用位置服务并等到应用程序真正停止(我等了60秒)
4)回到应用程序(在我的情况下,我的应用程序设置为在启动后立即更新,这将导致它在添加新注释之前尝试删除旧注释)
=&GT;这里应用程序会崩溃。
我通过自己的&#34; removeAnnotations调试它:&#34;迭代通过所有这些方法,我发现当它崩溃时,它试图删除一个比我最初添加的注释更多的注释。
如果未显示用户位置(由于其他原因导致位置服务从未启用),问题就不会发生,因此我认为这将是一种竞争,因为在上面的步骤3中禁用位置服务时,一旦发现位置服务被禁用,MKMapView将自动删除用户位置。但是,如果应用程序之前抓取了注释数组,它仍将包含用户位置,该位置由MKMapView在单独的线程中释放/销毁,因此竞争。
所以答案是你只需要删除你添加的注释。这是我的代码:
- (void)removeAnnotations
{
NSArray *currentAnnotations = [m_MapView annotations];
int count = [[m_MapView annotations] count];
if (currentAnnotations && count)
{
NSMutableArray *annotationsToRemove = [NSMutableArray arrayWithCapacity:count];
for (id annotation in currentAnnotations)
{
if ([annotation isKindOfClass:[MyAnnotation class]])
{
[annotationsToRemove addObject:annotation];
}
}
DBGLOG(@"removeAnnotations: current_count %d, to_be_removed_count %d\n", count, [annotationsToRemove count]);
[m_MapView removeAnnotations:annotationsToRemove];
annotationsToRemove = nil;
}
currentAnnotations = nil;
return;
}