Ocasionalmente iOS 6 MKMapView se bloquea en initWithFrame
ios6 ios6-maps (4)
Estoy enfrentando un rastro de pila similar. Noté que en la consola está dando más detalles sobre el problema real: no puedes usar la GPU mientras estás en segundo plano. Los mapas con iOS 5 estaban basados en mosaicos, así que supongo que no usaron la GPU, pero los nuevos mapas en iOS 6 usan gráficos vectoriales y, por lo tanto, la GPU. Como resultado, cualquier trabajo de mapa que solía estar en segundo plano ya no puede ser.
Tengo una aplicación en la tienda Apple Store y después de la actualización iOS6 tengo cientos de informes de MKMapView
dentro de MKMapView
. No logro reproducir el bloqueo en mis dispositivos. Parece un problema con EAGLContext
. No usamos OpenGL en nuestra aplicación, pero tenemos más de una instancia de MKMapView
en diferentes controladores. He encontrado un problema similar aquí. La aplicación iOS 6 se bloquea en EAGLContext al mostrar mapas pero usan OpenGL.
Aquí está la traza inversa:
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
.....
Estábamos teniendo un problema similar cuando el fondo del usuario nuestra aplicación justo cuando estamos apareciendo una ventana que incluye una subvista de mapa. El bloqueo parecía estar sucediendo debido a que el mapa usaba una llamada de OpenGL mientras estábamos en segundo plano. Tuvimos que ajustar la creación de la subvista del mapa en un cheque como el siguiente:
UIApplicationState appState = [[UIApplication sharedApplication] applicationState];
if( (appState != UIApplicationStateBackground) && (appState != UIApplicationStateInactive))
{
// Do map subview initialization...
}
else
{
self.attemptedToLoadMap = YES;
}
Guardamos el bool para que, si la aplicación vuelve al primer plano, podamos agregar la subvista para su visualización.
Tienes que hacer esto cada vez que manipulas el mapa de una manera que causa una operación de redibujado (por ejemplo, agregar una anotación).
http://developer.apple.com/library/ios/#qa/qa1766/_index.html
Este control de calidad técnico aborda este problema
Encontramos la causa de esto en nuestra aplicación, así que quería publicar la solución en caso de que ayudara a alguien más. Nuestro controlador de vista principal monitorea cambios de ubicación significativos cuando se muestra y detiene el monitoreo cuando está oculto. Algunos de nuestros usuarios experimentaron un bloqueo no relacionado en esta pantalla, lo que dejó a la aplicación monitoreando. Cuando una aplicación se ha registrado para actualizaciones significativas de cambios de ubicación, iOS realmente lanzará la aplicación en segundo plano si no se está ejecutando para informarle sobre la nueva ubicación. Dado que nuestra aplicación muestra un mapa cuando aparece por primera vez, esto causó un bloqueo. El soporte de Apple confirmó con nosotros que hay un error en los dispositivos de 32 bits que ejecutan iOS 8.x que puede causar un bloqueo si MapView (u otro contexto de OpenGL) se actualiza mientras la aplicación está en segundo plano.
Cambiamos nuestro código para que, si la aplicación se inicia debido a un cambio de ubicación significativo, dejamos de monitorear inmediatamente y lanzamos una excepción para bloquear la aplicación. Esto es completamente invisible para el usuario, por lo que no se da cuenta del bloqueo y evita que ocurran más bloqueos.
- (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:@{}];
}
}
Vimos miles de este bloqueo pero no pudimos duplicarlo en nuestros dispositivos de prueba hasta que descubrimos la causa. Si desea duplicarlo (y también confirmar la solución), @mita una excepción inmediatamente después de que su aplicación comience a monitorear cambios significativos de ubicación. Después de que la aplicación se cuelga, ve a dar un paseo. Tan pronto como su teléfono cambie a las torres de celulares, iOS lanzará la aplicación en segundo plano y obtendrá el bloqueo. Pudimos tener acceso a uno de los teléfonos de nuestros usuarios e inspeccionar los registros de fallos. Todos los accidentes ocurrieron durante su viaje de ida y vuelta al trabajo.