【问题标题】:iOS 7 mysterious crashiOS 7 神秘崩溃
【发布时间】:2013-09-25 15:28:14
【问题描述】:

我们在 AppStore 上有一款 iOS 游戏,一些用户在升级到 iOS 7 后报告了问题。我们已更新游戏以在 iOS 7 上运行,并已在多台设备上对其进行了广泛测试。但是,我们有一些用户报告崩溃,有时在我们测试并重新测试游戏的完全相同的设备上。 崩溃日志,符号化后,内容如下:

Thread 0 Crashed:
0   CoreGraphics                    0x2d4ec9ca CGColorSpaceGetModel + 10
1   QuartzCore                      0x2f893842 CA_CGColorGetRGBComponents + 30
2   QuartzCore                      0x2f95a142 -[NSObject(CAAnimatableValue) CA_distanceToValue:] + 86
3   UIKit                           0x2fe10c72 _UIViewLayerAnimationCanBeConsideredFinished + 250
4   UIKit                           0x2fe10ae2 __22-[UIWindow sendEvent:]_block_invoke + 10
5   CoreFoundation                  0x2d3c4022 __53-[__NSArrayI enumerateObjectsWithOptions:usingBlock:]_block_invoke + 50
6   CoreFoundation                  0x2d3bda0a -[__NSArrayI enumerateObjectsWithOptions:usingBlock:] + 218
7   UIKit                           0x2fc1b556 -[UIWindow sendEvent:] + 522
8   UIKit                           0x2fbf0a20 -[UIApplication sendEvent:] + 192
9   UIKit                           0x2fbef21c _UIApplicationHandleEventQueue + 7092
10  CoreFoundation                  0x2d446188 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 12
11  CoreFoundation                  0x2d445656 __CFRunLoopDoSources0 + 202
12  CoreFoundation                  0x2d443e4a __CFRunLoopRun + 618
13  CoreFoundation                  0x2d3aece2 CFRunLoopRunSpecific + 518
14  CoreFoundation                  0x2d3aeac6 CFRunLoopRunInMode + 102
15  GraphicsServices                0x320cf27e GSEventRunModal + 134
16  UIKit                           0x2fc50a3c UIApplicationMain + 1132
17  MyGame                          0x00104382 main (main.m:13)
18  MyGame                          0x0010435c ___lldb_unnamed_function455$$MyGame + 36

我完全不知道从这里去哪里,任何建议将不胜感激。

【问题讨论】:

  • 尝试在您的视图中检查彩色动画。也许你在某个地方执行从 [UIColor colorWithRed:green:blue:alpha:] 到 [UIColor whiteColor] 的动画?还是 [UIColor blackColor]?
  • 另一种可能的变体,即您的应用中有后台任务。部分 UI 代码可能会在后台执行并导致崩溃。
  • 还可以执行一些完成块,并可能更改已经不在视图层次结构中的视图属性。但这只是猜测 - 发布日志不足以修复崩溃 - 让 QA 团队准确检测用户操作的顺序导致崩溃,它将帮助您找出原因
  • @PetroKorienev 我的游戏中没有任何后台任务,即使我在图层上有一些动画可以更改填充颜色,但这些动画似乎已正确实现。谢谢
  • @PetroKorienev QA 团队?我也是;)

标签: ios crash ios7 crash-reports


【解决方案1】:

您的崩溃报告中缺少一些东西,主要是异常(释放的实例?缺少选择器?),但是我们仍然可以推断出一些东西:

[UIWindow sendEvent:]

这是来自事件处理的调用,可能是用户进行的触摸

我猜UIKit代码然后通过检查是否有一些活动动画_UIViewLayerAnimationCanBeConsideredFinished来检查是否可以传递事件。

我也猜测它是窗口层中的一些动画。您是在创建自己的窗口还是直接向UIWindow 添加视图?或者也许用动画改变根视图控制器?

无论如何,在动画期间尝试触摸屏幕,始终尝试正在出现的视图和正在消失的视图。

【讨论】:

  • 这与用户在短时间内两次点击屏幕时的两个动画交互有关。在崩溃时,我没有修改与 UIWindow 或根视图控制器相关的任何内容。由于这会导致生产崩溃,我只需要删除其中一个动画即可解决问题,但即使知道哪个动画是罪魁祸首,我也无法找出问题所在。在 iOS 7 之前,这两个动画似乎都配置正确并且运行良好。
  • @EliBud 你能分享更多关于动画的细节吗?
【解决方案2】:

我认为这是问题所在

5 CoreFoundation 0x2d3c4022 __53-[__NSArrayI enumerateObjectsWithOptions:usingBlock:]_block_invoke + 50

我将块枚举器用于交错动画,它导致我的应用程序崩溃,并显示消息“

[UIViewAnimationState release]: 消息发送到释放的实例

我正在使用 ARC 和静态方法调用,所以不确定为什么会发生这种情况。

但是,将此循环更改为 foreach 样式循环解决了该问题。块内的块在 iOS5 和 6 中运行良好,但给出了奇怪的结果,然后在 iOS7 中崩溃

【讨论】:

  • 我没有使用块枚举器来遍历任何一组动画,所以我很确定这不是我的问题。谢谢
  • _block_invoke 是否意味着崩溃发生在区块内?
【解决方案3】:

enumerateObjectsWithOptions:usingBlock 使用后台线程。如果其中一个后台线程确实在 GUI 对象上工作(当然动画也算在内),它将崩溃。

当崩溃发生时,转到 Xcode 的左侧并选择调试导航器。您很可能会在线程 x 不相等的线程 1 中看到崩溃。仅允许作为 GUI 线程的线程 1 使用 GUI。

要解决您的问题,您至少有两种选择:

a) 将您所做的动画 GUI 工作放在 dispatch_async 或 dispatch_sync 块中,例如

    …enumerateObjectsWithOptions:usingBlock … {

        // non GUI stuff    

        dispatch_async(dispatch_get_main_queue(), ^{ 
            // GUI work
            // non GUI stuff is also okay here
        });

        // non GUI stuff  

} // end of enumerateObjectsUsingBlock  

b) 使用快速枚举而不是 enumerateObjectsWithOptions:usingBlock 并以这种方式避免后台线程。

我猜 iOS 7 使用了更多的内部线程,也许 iOS 6 无法在这些调用中使用后台线程,因此在 6 上并没有在 7 上造成问题。

玩得开心!

【讨论】:

  • 我根本没有使用 enumerateObjectsWithOptions:usingBlock。无论如何,我最终不得不删除动画,因为我找不到问题的根本原因。
  • 您的崩溃日志包含“NSArrayI enumerateObjectsWithOptions:usingBlock:”;-)
  • 我知道有,但它在 CoreFundation 代码中,不是我的。
  • 日志显示错误发生在 thread0 上 - 所以虽然这是真的,但我认为这个答案无效