我在苹果商店有一个应用程序,在iOS6更新后,我在MKMapView
内收到了数百份崩溃报告。我无法在我的设备上重现崩溃。它似乎是EAGLContext
的问题。我们不在我们的应用程序中使用OpenGL,但我们在不同的控制器中有多个MKMapView
实例。
我在iOS 6 app crashes in EAGLContext when displaying maps找到了类似的问题,但他们使用的是OpenGL。
这里有回溯:
Exception Type: SIGSEGV
Exception Codes: SEGV_ACCERR at 0x1
Crashed Thread: 0
Thread 0 Crashed:
0 libGPUSupportMercury.dylib 0x00000e22 gpus_ReturnNotPermittedKillClient + 10
1 libGPUSupportMercury.dylib 0x3bccc5fb gldCreateContext + 190
2 GLEngine 0x344c2b15 gliCreateContextWithShared + 676
3 OpenGLES 0x0000491d -[EAGLContext initWithAPI:properties:] + 1433
4 OpenGLES 0x000042d7 -[EAGLContext initWithAPI:sharedWithCompute:] + 143
5 VectorKit 0x00011c81 -[VGLGPU init] + 105
6 VectorKit 0x000d4659 __24+[VGLGPU sharedInstance]_block_invoke_0 + 49
7 libdispatch.dylib 0x000014b7 _dispatch_client_callout + 23
8 libdispatch.dylib 0x000073f7 dispatch_once_f$VARIANT$mp + 43
9 VectorKit 0x00011c13 +[VGLGPU sharedInstance] + 39
10 VectorKit 0x00001db1 -[VKMainLoop updateLinkState] + 485
11 VectorKit 0x00001955 -[VKScreenCanvas _updateDisplayStatus:] + 109
12 UIKit 0x0001c371 -[UIView initWithFrame:] + 129
13 VectorKit 0x00010ca5 -[VGLScreenCanvas initWithFrame:context:] + 53
14 VectorKit 0x00010a7d -[VKScreenCanvas initWithFrame:context:] + 57
15 VectorKit 0x00010a3f -[VKScreenCanvas initWithFrame:] + 39
16 VectorKit 0x000106bd -[VKMapCanvas initWithFrame:shouldRasterize:] + 65
17 VectorKit 0x000104bb -[VKMapView initWithFrame:andGlobe:shouldRasterize:] + 647
18 MapKit 0x0000dc95 -[MKMapView _commonInitAndEnableLoading:fromIB:] + 725
19 MapKit 0x0000d811 -[MKMapView initWithFrame:] + 257
.....
答案 0 :(得分:24)
当我们弹出一个包含地图子视图的窗口时,我们遇到了类似的问题。由于地图在我们背景时使用openGL调用,似乎发生了崩溃。我们必须将地图子视图创建包装在如下的检查中:
UIApplicationState appState = [[UIApplication sharedApplication] applicationState];
if( (appState != UIApplicationStateBackground) && (appState != UIApplicationStateInactive))
{
// Do map subview initialization...
}
else
{
self.attemptedToLoadMap = YES;
}
我们保存了bool,以便如果应用程序返回到前台,我们可以添加子视图以供显示。
当您以导致重新绘制操作的方式操作地图时(例如,添加注释),您必须随时执行此操作。
答案 1 :(得分:3)
答案 2 :(得分:3)
我们在我们的应用程序中找到了这个原因,所以我想发布解决方案,以防它可以帮助其他人。我们的主视图控制器在显示时监视重要的位置更改,并在隐藏时停止监视。我们的一些用户在此屏幕上遇到了无关的崩溃,导致应用程序无法监控。当应用程序注册了重要的位置更改更新时,如果应用程序未运行,则会实际将应用程序启动到后台以告知其新位置。由于我们的应用程序首次出现时会显示地图,因此会导致崩溃。 Apple支持向我们证实,运行iOS 8.x的32位设备存在一个错误,如果在应用程序处于后台时更新了MapView(或其他OpenGL上下文),则可能会导致崩溃。
我们更改了代码,以便在应用程序因重大位置更改而启动时,我们会立即停止监控并抛出异常以使应用程序崩溃。这对用户完全不可见,因此他们不会注意到崩溃,并且可以防止进一步的崩溃。
- (void)validateLaunchWithOptions:(NSDictionary *)launchOptions
{
if (launchOptions[@"UIApplicationLaunchOptionsLocationKey"]) {
// the app was launched due to a significant location change, which is not valid and causes crashes
// prevent this from happening again by disabling significant location monitoring
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
[locationManager stopMonitoringSignificantLocationChanges];
// intentionally crashing the app here; it is not in a good state and it needs to be prevented from
// getting to any code that would re-enable significant location monitoring
@throw [NSException exceptionWithName:@"com.redacted.significantLocationLaunch"
reason:@"app may not be launched due to significant location changes"
userInfo:@{}];
}
}
我们看到了数千这次崩溃,但在我们找出原因之前无法在我们的测试设备上复制它。如果您想复制它(并确认修复),请在应用程序开始监控重要位置更改后立即@throw异常。应用崩溃后,去开车吧。一旦您的手机切换手机信号塔,iOS将在后台启动应用程序,您将收到崩溃。我们能够接通用户的一部用户手机并检查崩溃日志。所有的撞车事故都发生在她上班和下班途中。
答案 3 :(得分:2)
我面对类似的堆栈跟踪。我注意到在控制台中它提供了更多有关实际问题的详细信息:您无法在后台使用GPU。 iOS 5的地图是基于图块的,因此我假设没有使用GPU,但iOS 6中的新地图使用矢量图形,因此使用GPU。因此,以前在后台的任何地图工作都不再是。