Подтвердить что ты не робот

Иногда iOS 6 MKMapView падает в initWithFrame

У меня есть приложение в магазине Apple, и после обновления iOS6 у меня есть сто отчетов о сбоях в MKMapView. Я не могу воспроизвести крах на своих устройствах. Это выглядит как проблема с EAGLContext. Мы не используем OpenGL в нашем приложении, но у нас есть несколько экземпляров MKMapView в разных контроллерах. Я нашел аналогичную проблему здесь iOS 6 сбой приложений в EAGLContext при отображении карт, но они используют 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
.....
4b9b3361

Ответ 1

У нас возникла аналогичная проблема, когда пользователь заглядывал в наше приложение так же, как мы выворачиваем окно, которое включает в себя подкласс отображения. Похоже, что авария произошла из-за карты, используя вызов openGL, когда мы находимся в фокусе. Нам пришлось обернуть создание подзаголовка карты в чеке, как показано ниже:

UIApplicationState appState = [[UIApplication sharedApplication] applicationState];
    if( (appState != UIApplicationStateBackground) && (appState != UIApplicationStateInactive))
    {
        // Do map subview initialization...
    }
    else
    {
        self.attemptedToLoadMap = YES;
    }

Мы сэкономили bool, так что, если приложение вернется на передний план, мы можем добавить subview для отображения.

Вы должны делать это в любое время, когда вы манипулируете картой таким образом, который вызывает операцию повторного рисования (например, добавление аннотации).

Ответ 3

Мы нашли причину этого в нашем приложении, поэтому я захотел опубликовать решение, если оно поможет кому-то еще. Наш основной контроллер просмотра контролирует значительные изменения местоположения при его отображении и прекращает мониторинг, когда он скрыт. Некоторое количество наших пользователей столкнулось с несвязанным сбоем на этом экране, что оставило мониторинг приложений. Когда приложение зарегистрировалось для значительных обновлений изменения местоположения, iOS фактически запустит приложение в фоновом режиме, если оно не будет запущено, чтобы рассказать об этом новом местоположении. Поскольку наше приложение отображает карту, когда она впервые появляется, это вызвало сбой. Поддержка Apple подтвердила, что на 32-разрядных устройствах под управлением iOS 8.x есть ошибка, которая может привести к сбою, если 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 запустит приложение в фоновом режиме, и вы получите крах. Мы смогли получить доступ к одному из наших телефонов пользователей и проверить журналы сбоев. Все аварии произошли во время ее поездок на работу и с работы.

Ответ 4

Я столкнулся с аналогичной трассировкой стека. Я заметил, что в консоли он дает больше информации о реальной проблеме: вы не можете использовать GPU в фоновом режиме. Карты с iOS 5 были основаны на плитке, поэтому я предполагаю, что не использовал GPU, но новые карты в iOS 6 используют векторную графику и, следовательно, графический процессор. В результате любая работа с картами, которая раньше была в фоновом режиме, больше не может быть.