繁体   English   中英

CoreGraphics / MapKit中的调试崩溃

[英]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。

这里有几件事要牢记:

  1. 每个位置不要添加太多叠加层。 1就足够了。 50是过度杀伤力。
  2. 每个位置一个MKCircle就足够了。 不确定为什么选择跟踪并在每个位置绘制这么多的圆圈。
  3. 尝试更有效地将叠加层移交给MapView。 仅为其提供所显示的地图部分所需的叠加层。 观看WWDC2011视频“ Session 111-使用MapKit地理可视化信息”,该视频演示了如何优化此代码或HazardMap示例代码。

您可以按照以下方式进行操作:

-(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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM