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

标签 objective-c ios crash

(见底部更新)

最近,当我的 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 在堆栈跟踪和崩溃的时间猜测),但是:
  • 我的类(class)都没有注册 UIApplicationDidBecomeActiveNotification ,并且只有几个单例(永远活着)注册UIApplicationWillEnterForegroundNotification ;
  • 我做了一些实验,结果发现发布 UIApplicationWillEnterForegroundNotification来自 [UIApplication _sendWillEnterForegroundCallbacks:] ,并且它不在崩溃日志中。

  • 对我来说,所有这些都意味着我正在使用的某个库中存在错误,或者系统错误,并且崩溃发生在 iOS 5.1.1(发布版本)、iOS 6.0(发布版本)和 iOS 6.0 上一次(调试构建)。我扫描了我正在使用的每个库并可以访问其源代码,但它们都没有注册 UIApplicationWillEnterForegroundNotification也不是 UIApplicationDidBecomeActiveNotification .我唯一无法访问的库是 TestFlight,但崩溃发生在 TestFlight 的 1.0 和 1.1 版本上,我已经使用前者很长一段时间了,没有出现此类问题。
    所以,总而言之,我不知道为什么会出现这种崩溃以及它来自什么。有任何想法吗?

    更新 1

    感谢 DarthMike 和 matt 的帮助,我对这个问题进行了更深入的调查。通过使用通知中心回调和记录堆栈跟踪,我发现当且仅当 UIApplicationResumedNotification 时才会出现这个确切的堆栈。通知作为从后台返回的一部分被触发。你猜怎么着——这是一些“私有(private)”通知,它没有对应的公共(public)标识符。它没有 userInfo它的对象是UIApplication (与在此之前发布的许多其他通知一样)。显然我不使用它,我也没有任何库我有源代码。我什至在互联网上找不到任何合理的提及!我也高度怀疑 TestFlight 是罪魁祸首,因为在调试期间也发生了崩溃,而且我不会在 Debug模式下“起飞”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 的观察者。并且在观察者被释放之前没有删除它。基于我从未注册过此类通知的事实,我可以假设这次崩溃不是我的错。问题仍然存在——那是谁呢?我想知道谁实际上注册了这个通知......

    更新 2

    虽然我仍在等待查看我的应用程序的新版本上的这个错误是否有任何变化,但我在以前的版本中又遇到了一次崩溃。事实证明,UIApplicationResumedNotification 的任何寄存器, 指定选择器 _applicationResuming:为了它。我怀疑这有什么用。

    最佳答案

    在运行 IOS 6.0.1 的设备的崩溃报告中,我有完全相同的堆栈跟踪。我设法通过以下模式在模拟器上重现了该问题:

  • 将应用置于后台
  • 从模拟器菜单模拟内存警告
  • 让应用程序回到前台

  • 经过大量调试后,我发现 _applicationResuming: 消息被发送到 UITextField,我将其作为对内存警告的 react 而发布。我在 IOS 5.1 下测试了相同的模式,但它没有导致崩溃。出于某种原因,在 IOS 6 UITextField 中为 ApplicationResumeEvent 注册(可能并不总是,但在键盘出现之后)。
    我的解决方法是在释放它之前从 NSNotificationCenter 中删除它:
    [[NSNotificationCenter defaultCenter] removeObserver:self.placeFld];
    self.placeFld = nil;
    

    关于objective-c - iOS 应用程序在恢复时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12601406/

    相关文章:

    android - 我想创建一个+评分系统

    ios - 是否可以在没有用户交互的情况下关闭 MFMailComposeViewController?

    ios - UITabBarController 中更多项目的自定义图像和/或标题

    ios - __block 修饰符创建不可读的内存

    ios - 错误域=NSOSStatusErrorDomain 代码=1954115647 "(null)"

    ios - 条件绑定(bind)的初始化程序必须具有可选类型,而不是 'AVCaptureVideoPreviewLayer'

    c++ - 捕获 C++ 库崩溃的一致方法

    java - Java-MySQL高负载应用程序崩溃

    objective-c - Xcode 无法在模拟设备 “iPhone 6 Plus” 上启动应用程序,因为它当前正在运行应用程序

    iphone - 在iPhone上使用sqlite3_create_collat​​ion