Objective-c – iOS应用程序在恢复时崩溃

前端之家收集整理的这篇文章主要介绍了Objective-c – iOS应用程序在恢复时崩溃前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
(见底部更新)

最近,当我的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,只有几个单身(永远活着)注册UIApplicationWillEnterForegroundNotification;
>我已经做了一些实验,事实证明,发布UIApplicationWillEnterForegroundNotification从[UIApplication _sendWillEnterForegroundCallbacks:],它不在崩溃日志中.

对我来说,这一切意味着我正在使用的某个库中出现错误,或系统错误,并且在iOS 5.1.1(发布版本)上发生了一次崩溃,一次在iOS 6.0(发布版本)上,一次在iOS 6.0(调试构建).我扫描了我正在使用的每个图书馆,并且可以访问源代码,并且不会注册UIApplicationWillEnterForegroundNotification或UIApplicationDidBecomeActiveNotification.我无法访问的唯一的库是TestFlight,但崩溃发生在1.0和1.1版本的TestFlight上,而且我一直在使用前一段时间,没有这样的问题.
所以,总结一下,我不知道为什么这个崩溃来了,它是怎么来的.有任何想法吗?

更新1

我已经调查了这个问题,感谢DarthMike和matt的帮助.通过使用通知中心回调和日志记录堆栈跟踪,我发现当且仅当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,随后在objc_msgSend 16中与EXC_BAD_ACCESS发生崩溃,就像我原来的崩溃一样.
所以这只是意味着有人注册了一个UIApplicationResumedNotification的观察者,并且在观察者被释放之前没有删除它.基于我从未注册过这样的通知,我可以假设这个崩溃不是我的错.仍然存在问题 – 那是谁呢?我不知道谁实际上注册了这个通知

更新2

虽然我还在等待看到我的应用程序的新版本是否有这个错误的任何更改,但是由于此原因,我还有另一次崩溃.结果是UIApplicationResumedNotification的任何寄存器,指定选择器_applicationResuming:为它.我怀疑这是有什么用的.

解决方法

我刚刚遇到这个问题,发现一个解决方案不涉及删除通知.在我们的例子中,有一些旧代码是这样做的:
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
  [searchBar resignFirstResponder];
  // other stuff
}

我不知道为什么我们有这个,但现在已经走了,崩溃了.看起来在这种情况下,当searchBarTextDidBeginEditing被调用搜索栏的文本编辑字段上时,通知就被撤回,然后一旦拥有这个UISearchBar的视图控制器被释放,并且我们做了后台/前台舞蹈.

因人而异

猜你在找的C&C++相关文章