Приложение iOS вылетает при возобновлении
(SEE UPDATE AT THE BOTTOM)
Недавно у меня началось странное и редкое падение моего приложения для iPhone, когда оно возвращалось из фона. Журнал сбоев состоит только из системных вызовов:
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x00000138
Crashed Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libobjc.A.dylib 0x34c715b0 objc_msgSend + 16
1 CoreFoundation 0x368b7034 _CFXNotificationPost + 1424
2 Foundation 0x34379d8c -[NSNotificationCenter postNotificationName:object:userInfo:] + 68
3 UIKit 0x37ddfec2 -[UIApplication _handleApplicationResumeEvent:] + 1290
4 UIKit 0x37c37d5c -[UIApplication handleEvent:withNewEvent:] + 1288
5 UIKit 0x37c376d0 -[UIApplication sendEvent:] + 68
6 UIKit 0x37c3711e _UIApplicationHandleEvent + 6150
7 GraphicsServices 0x36dea5a0 _PurpleEventCallback + 588
8 CoreFoundation 0x3693b680 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 12
9 CoreFoundation 0x3693aee4 __CFRunLoopDoSources0 + 208
10 CoreFoundation 0x36939cb2 __CFRunLoopRun + 642
11 CoreFoundation 0x368aceb8 CFRunLoopRunSpecific + 352
12 CoreFoundation 0x368acd44 CFRunLoopRunInMode + 100
13 GraphicsServices 0x36de92e6 GSEventRunModal + 70
14 UIKit 0x37c8b2fc UIApplicationMain + 1116
15 [MyAppName] 0x00083d60 main (main.m:20)
16 [MyAppName] 0x00080304 start + 36
Это может выглядеть как объект зомбиUIApplicationWillEnterForegroundNotification
или жеUIApplicationDidBecomeActiveNotification
(угадывая_handleApplicationResumeEvent
в трассировке стека и в момент сбоя), но:
UIApplicationDidBecomeActiveNotification
, and only a couple of singletons (that stay alive forever) register for UIApplicationWillEnterForegroundNotification
;
I've done some experimenting, and it turns out that posting UIApplicationWillEnterForegroundNotification
goes from [UIApplication _sendWillEnterForegroundCallbacks:]
, and it isn't in the crash log.
Для меня все это подразумевает ошибку в какой-то библиотеке, которую я использую, или системную ошибку, и сбой произошел один раз на iOS 5.1.1 (сборка выпуска), один раз на iOS 6.0 (сборка выпуска) и один раз на iOS 6.0 ( отладочная сборка). Я отсканировал все библиотеки, которые я использую, и имею доступ к исходному коду, а они не регистрируются ни на одну из них.UIApplicationWillEnterForegroundNotification
ниUIApplicationDidBecomeActiveNotification
, Единственной библиотекой, к которой у меня нет доступа, является TestFlight, но сбой произошел в обеих версиях TestFlight версий 1.0 и 1.1, и я уже довольно давно использую первую без таких проблем.
Итак, подводя итог, я понятия не имею, почему возникла эта авария и откуда она взялась. Есть идеи?
UPDATE 1
Я исследовал проблему немного глубже, благодаря DarthMike и Мэтту за их помощь. Используя обратный вызов центра уведомлений и трассировку стека журналов, я обнаружил, что этот точный стек появляется тогда и только тогда, когдаUIApplicationResumedNotification
уведомление запускается как часть возвращения из фона. И угадайте, что это - какое-то "личное" уведомление, и оно не имеет аналога открытого идентификатора. Это не имеетuserInfo
и его цельUIApplication
(как и многие другие уведомления, которые публикуются до этого). Очевидно, что я им не пользуюсь, равно как и библиотека, для которой у меня есть исходный код. Я даже не могу найти разумного упоминания об этом в Интернете! Я также очень сомневаюсь в том, что TestFlight является виновником, потому что сбой произошел также во время отладки, и я не "снимаю" TestFlight в режиме отладки.
Здесь трассировка стека для приемаUIApplicationResumedNotification
, Смещения все одинаковые, но с постоянным байтовым смещением (2 или 4, в зависимости от библиотеки - возможно, потому, что это трассировка стека отладки, а не выпуска):
0 [MyAppName] 0x0016f509 NotificationsCallback + 72
1 CoreFoundation 0x3598ce25 __CFNotificationCenterAddObserver_block_invoke_0 + 124
2 CoreFoundation 0x35911037 _CFXNotificationPost + 1426
3 Foundation 0x333d3d91 -[NSNotificationCenter postNotificationName:object:userInfo:] + 72
4 UIKit 0x36e39ec7 -[UIApplication _handleApplicationResumeEvent:] + 1294
5 UIKit 0x36c91d61 -[UIApplication handleEvent:withNewEvent:] + 1292
6 UIKit 0x36c916d5 -[UIApplication sendEvent:] + 72
7 UIKit 0x36c91123 _UIApplicationHandleEvent + 6154
8 GraphicsServices 0x35e445a3 _PurpleEventCallback + 590
9 CoreFoundation 0x35995683 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 14
10 CoreFoundation 0x35994ee9 __CFRunLoopDoSources0 + 212
11 CoreFoundation 0x35993cb7 __CFRunLoopRun + 646
12 CoreFoundation 0x35906ebd CFRunLoopRunSpecific + 356
13 CoreFoundation 0x35906d49 CFRunLoopRunInMode + 104
14 GraphicsServices 0x35e432eb GSEventRunModal + 74
15 UIKit 0x36ce5301 UIApplicationMain + 1120
16 [MyAppName] 0x000aa603 main + 390
17 [MyAppName] 0x000a41b0 start + 40
NotificationsCallback является «наблюдателем»; обратный вызов, который я только что добавил для отладки.
Просто чтобы доказать свою точку зрения, я намеренно опустилremoveObserver:
вызов из одного из моих объектов для генерации зомби / исключения, и трассировка стека все еще включена_CFXNotificationPost + 1426
последовал сбой сEXC_BAD_ACCESS
вobjc_msgSend + 16
так же, как в моем оригинальном сбое.
Так что это просто означает, что кто-то зарегистрировал наблюдателя дляUIApplicationResumedNotification
и не удалили его до того, как наблюдатель был освобожден. Исходя из того, что я никогда не регистрировался для такого уведомления, я могу предположить, что этот сбой не моя вина. И все же остается вопрос - а кто это тогда? Интересно, кто на самом деле регистрируется для этого уведомления в любом случае ...
UPDATE 2
Хотя я все еще жду, чтобы увидеть, есть ли какие-либо изменения с этой ошибкой в новой версии моего приложения, у меня произошел другой сбой в предыдущей версии, вызванный этим. Оказывается, что все регистрируется дляUIApplicationResumedNotification
, указывает селектор_applicationResuming:
для этого. Я сомневаюсь, что это хоть какое-то использование.