iOS 应用程序在恢复时崩溃 [英] iOS app crashes on resuming

查看:29
本文介绍了iOS 应用程序在恢复时崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(见底部更新)

最近,当我的 iPhone 应用程序从后台返回时,我开始遇到奇怪且罕见的崩溃.崩溃日志仅包含系统调用:

Recently I've started getting a weird and rare crash of my iPhone app when it returns from background. The crash log consists of system calls only:

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

这可能看起来像在 UIApplicationWillEnterForegroundNotificationUIApplicationDidBecomeActiveNotification 上调用的僵尸对象(由堆栈跟踪中的 _handleApplicationResumeEvent 猜测以及它崩溃的时间),但是:

This might look like a zombie object being called on UIApplicationWillEnterForegroundNotification or UIApplicationDidBecomeActiveNotification (guessing by _handleApplicationResumeEvent in stack trace and the time when it crashes), but:

  1. 我的所有类都没有注册 UIApplicationDidBecomeActiveNotification,只有几个单身人士(永远活着)注册了 UIApplicationWillEnterForegroundNotification
  2. 我做了一些实验,结果发现发布 UIApplicationWillEnterForegroundNotification 来自 [UIApplication _sendWillEnterForegroundCallbacks:],并且它不在崩溃日志中.
  1. None of my classes register for UIApplicationDidBecomeActiveNotification, and only a couple of singletons (that stay alive forever) register for UIApplicationWillEnterForegroundNotification;
  2. 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 版本上,我已经使用前者很长一段时间了,没有出现此类问题.所以,总而言之,我不知道为什么会出现这种崩溃以及它来自什么.有什么想法吗?

For me, all this implies a bug in some library I'm using, or a system bug, and the crash occurred once on iOS 5.1.1 (release build), once on iOS 6.0 (release build) and once on iOS 6.0 (debug build). I scanned every library I'm using and have access to the source code for, and they aren't registering for neither UIApplicationWillEnterForegroundNotification nor UIApplicationDidBecomeActiveNotification. The only library I don't have access to is TestFlight, but the crash occurred on both 1.0 and 1.1 versions of TestFlight, and I've been using the former for quite a while now, without such problems. So, summing up, I have no idea why has this crash come up and what's it coming from. Any ideas?

更新 1

感谢 DarthMike 和 matt 的帮助,我对这个问题进行了更深入的调查.通过使用通知中心回调和记录堆栈跟踪,我发现当且仅当 UIApplicationResumedNotification 通知作为从后台返回的一部分被触发时,才会出现这个确切的堆栈.你猜怎么着——这是一些私人"通知,它没有对应的公共标识符.它没有 userInfo 并且它的对象是 UIApplication (与之前发布的许多其他通知一样).显然我不使用它,我也没有任何库我有源代码.我什至在互联网上找不到任何合理的提及!我也非常怀疑TestFlight是罪魁祸首,因为在调试过程中也发生了崩溃,而且我不会在调试模式下起飞"TestFlight.

I've investigated the issue a bit deeper, thanks to DarthMike and matt for their help. By using notification center callback and logging stack trace, I've discovered that this exact stack comes up when and only when UIApplicationResumedNotification notification is fired as a part of returning from background. And guess what - it's some "private" notification and it doesn't have a public identifier counterpart. It doesn't have userInfo and its object is UIApplication (as many other notifications that are posted before this). Obviously I don't use it, neither does any library I have source code for. I can't even find any reasonable mentioning of it in the Internet! I also highly doubt that TestFlight is the culprit, because crash happened during debug too, and I don't "take off" TestFlight in debug mode.

这是接收 UIApplicationResumedNotification 的堆栈跟踪.偏移量都是相同的,但具有恒定的字节偏移量(2 或 4,取决于库 - 可能是因为它是调试堆栈跟踪,而不是发布):

Here's the stack trace for receiving UIApplicationResumedNotification. The offsets are all the same but with a constant byte offset (2 or 4, depending on the library - probably because it's a debug stack tracing, not release):

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 是我为调试添加的观察者"回调.

NotificationsCallback is an "observer" callback I've added for debug just for now.

为了证明一点,我故意从我的一个对象中省略了 removeObserver: 调用以生成僵尸/异常,并且堆栈跟踪仍然包含 _CFXNotificationPost + 1426 然后在 objc_msgSend + 16 中出现 EXC_BAD_ACCESS 崩溃,就像我最初的崩溃一样.所以这只是意味着有人已经为 UIApplicationResumedNotification 注册了一个观察者,并且在观察者被释放之前没有删除它.基于我从未注册过此类通知的事实,我可以假设这次崩溃不是我的错.问题仍然存在——那是谁呢?我想知道到底是谁注册了这个通知......

Just to prove a point, I've deliberately omitted a removeObserver: call from one of my objects to generate a zombie/exception, and stack trace still included _CFXNotificationPost + 1426 followed by a crash with EXC_BAD_ACCESS in objc_msgSend + 16, just as in my original crash. So this just means that someone has registered an observer for UIApplicationResumedNotification and haven't removed it before the observer was deallocated. Based on the fact that I never registered for such a notification, I can assume that this crash is not my fault. Still the question remains - whose it is then? I wonder who actually registers for this notification anyway...

更新 2

虽然我仍在等待查看我的应用程序的新版本中的此错误是否有任何更改,但我在之前的版本中遇到了另一个由此导致的崩溃.事实证明,对于 UIApplicationResumedNotification 的任何寄存器,都会为其指定选择器 _applicationResuming:.不过我怀疑这有什么用.

While I'm still waiting to see if there are any changes with this bug on the new version of my app, I've got another crash on the previous version caused by this. Turns out that whatever registers for UIApplicationResumedNotification, specifies selector _applicationResuming: for it. I doubt that's of any use though.

推荐答案

我刚遇到这个问题,找到了一个不涉及删除通知的解决方案.在我们的例子中,有一个旧代码正在这样做:

I just ran into this issue and found a solution that did not involve removing notifications. In our case, there was old code that was doing this:

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
  [searchBar resignFirstResponder];
  // other stuff
}

我不知道我们为什么会有这个,但现在它已经消失了,崩溃也消失了.似乎在这种情况下,在调用 searchBarTextDidBeginEditing 时辞职第一响应者会孤立搜索栏的文本编辑字段上的通知,然后一旦拥有此 UISearchBar 的视图控制器被释放并且我们执行了背景/前景,我们就会崩溃跳舞.

I do not know why we had this, but it is gone now and the crash is gone. It appears that in this case, resigning first responder while searchBarTextDidBeginEditing is being called orphans a notification on the search bar's text edit field, and then we'd crash as soon as the view controller owning this UISearchBar was deallocated and we did the background / foreground dance.

YMMV

这篇关于iOS 应用程序在恢复时崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆