[英]Debugging crash in CoreGraphics/MapKit
当我的应用程序在iPhone上运行时,我间歇性崩溃。 所有崩溃都是相同的,并且以某种方式涉及MKMapView叠加层(MKCircleViews)。
根据典型的iPhone 4s崩溃报告:
报告标题:
Hardware Model: iPhone4,1
Process: EL-GPS-01 [1021]
Path: /var/mobile/Applications/61288E15-74B5-45B9-99A9-E0B58C767816/EL-GPS-01.app/EL-GPS-01
Identifier: EL-GPS-01
Version: ??? (???)
Code Type: ARM (Native)
Parent Process: launchd [1]
Date/Time: 2011-11-22 15:59:41.065 +0000
OS Version: iPhone OS 5.0.1 (9A405)
Report Version: 104
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x00000000
Crashed Thread: 6
和崩溃的线程:
Thread 6 name: Dispatch queue: com.apple.root.default-priority
Thread 6 Crashed:
0 ??? 0000000000 0 + 0
1 CoreGraphics 0x319a87c2 0x31967000 + 268226
2 CoreGraphics 0x3199a9e6 0x31967000 + 211430
3 MapKit 0x37ec3564 0x37e6f000 + 345444
4 MapKit 0x37ec3652 0x37e6f000 + 345682
5 MapKit 0x37ecc0a4 0x37e6f000 + 381092
6 QuartzCore 0x3341be18 0x33410000 + 48664
7 QuartzCore 0x334d77e0 0x33410000 + 817120
8 QuartzCore 0x3346af24 0x33410000 + 372516
9 libdispatch.dylib 0x3797e892 0x3797b000 + 14482
10 libsystem_c.dylib 0x360e31ca 0x360d9000 + 41418
11 libsystem_c.dylib 0x360e30a0 0x360d9000 + 41120
当我的iPhone连接到笔记本电脑时,应用程序崩溃时,我的输出面板中显示以下内容:
warning: check_safe_call: could not restore current frame
warning: Unable to restore previously selected frame.
调试器什么也没给我,问题导航器显示崩溃的线程,堆栈上什么也没有。
这里有一个非常简单的项目,突出了这个问题:
https://github.com/1ndivisible/MKOverlayBug
git@github.com:1ndivisible / MKOverlayBug.git
我不确定该如何处理。 这里有什么我可以使用的信息吗? 崩溃似乎起源于框架的深处。
我认为您的内存不足或正在遇到MapKit中的错误。 但是从防御的角度看,您似乎并没有正确使用叠加层和MK视图,并且在跟踪许多潜在叠加层的情况下使MKMapView负担过多。 举个例子。 使用以下方法时,您要将50个叠加层添加到当前位置:
-(void)addOverlays
{
CLLocation *currentLocation = self.mapView.userLocation.location;
for(int i = 0; i < 50; i++)
{
MKCircle *circle = [MKCircle circleWithCenterCoordinate:currentLocation.coordinate radius:50];
[self.mapView addOverlay:circle];
}
}
随着时间的流逝,这可能会增加MKMapView需要跟踪的大量叠加层以及可能必须立即显示的MKViews。 使用您的示例代码和iPhone模拟器的位置模拟器,简单的自行车骑行路线在MKMapView中累积了1800多个MKCircle和MKCircleViews。
这里有几件事要牢记:
您可以按照以下方式进行操作:
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
// Add it to an NSArray that you use to keep track of ALL the overlays
[self.allOverlays addObject: MKCircle *circle = [MKCircle circleWithCenterCoordinate:currentLocation.coordinate radius:50]];
// Now add it to the mapView if it is in the current region
// code to check to see if currentLocation is within the current map region
if (overlayIsInMapRegion){
[mapView addOverlay: circle];
}
}
然后,每当区域更改时,计算MapView调用委托方法时所需的叠加层:
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
从mapView获取区域,并创建一个位于该区域的叠加层数组。 类似于以下内容:
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
// Create a method that takes the region and calculates which overlays it contains
NSArray *newOverlays=[self overlaysForRegion: mapView.region fromAllOverlays: self.allOverlays];
if ([newOverlays count]>0){
[mapView removeOverlays];
[mapView addOverlays: newOverlays];
}
}
希望这可以帮助。 祝好运!
提姆
它是一个已知的错误。 苹果已经承认了。 目前没有修复。 您所要做的就是将图形添加到更少的注释中。 我发现<= 3注释是安全的。
KERN_INVALID_ADDRESS at 0x00000000损坏的线程:6
这告诉您某些尝试取消引用空指针的操作。 您可能发布了批注,或者在不应该批注的情况下发布了一些属于批注的数据。 在启用了僵尸的调试器下运行该应用程序,然后查看得到的结果。
此外,在项目上运行静态分析器,并更正其发现的所有问题。
在这种情况下,它可能试图在地址0处执行代码(而不是从那里访问数据。)如果再次使它崩溃,则请检查PC寄存器中的值。 如果该值为零,那么您将以零执行,而不是获取数据。
如果是这种情况,则可能是您的堆栈在执行期间被破坏了。 局部变量的某些缓冲区溢出可能会将零放入堆栈帧的返回地址。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.