【问题标题】:NSZombies are eating my app's brain!NSZombies 正在吃掉我的应用程序的大脑!
【发布时间】:2009-07-29 08:21:21
【问题描述】:

我遇到了保留/释放问题。我的视图非常复杂,所以我将 NSZombieEnabled 设置为 YES 并试图找出究竟是哪个对象让我感到悲伤。为了加快这个过程,我想知道是否有提示或技巧可以追踪僵尸回到他们挖出的坟墓(对不起,不得不),或者回到与他们相关的物体?神秘的控制台消息似乎没有提供太多洞察力:

NSInvocation: warning: object 0x1076850 of class '_NSZombie_CALayer' does not implement methodSignatureForSelector: -- trouble ahead

我没有称为“前面的麻烦”的选择器。

编辑 - 包括堆栈跟踪:

#0  0x3026e017 in ___forwarding___
#1  0x3024a0a2 in __forwarding_prep_0___
#2  0x302042e8 in CFRelease
#3  0x00c4fc31 in CALayerUpdateSublayers
#4  0x00c4e173 in -[CALayer dealloc]
#5  0x00c4000e in CALayerRelease
#6  0x00c48dad in CALayerFreeTransaction
#7  0x00c410b8 in CA::Transaction::commit
#8  0x00c492e0 in CA::Transaction::observer_callback
#9  0x30245c32 in __CFRunLoopDoObservers
#10 0x3024503f in CFRunLoopRunSpecific
#11 0x30244628 in CFRunLoopRunInMode
#12 0x32044c31 in GSEventRunModal
#13 0x32044cf6 in GSEventRun
#14 0x309021ee in UIApplicationMain
#15 0x00001eb4 in main at main.m:14

编辑 2:ObjectAlloc

在 ObjectAlloc 中查找有问题的内存地址,我找到了两个匹配项:

#    Address     Category           Creation Time      Size Responsible Library Responsible Caller
0   0x1076980   GeneralBlock-48    00:11.470       48      QuartzCore  -[CALayer setDelegate:]
1   0x1076980   CALayer            00:11.552       48      UIKit       -[UIView _createLayerWithFrame:]

深入研究#0 GeneralBlock-48:

#   Category        Event Type  Timestamp   Address Size    Responsible Library Responsible Caller
0   GeneralBlock-48 Malloc      00:11.470   0x1076980   48  QuartzCore  -[CALayer setDelegate:]
1   GeneralBlock-48 Free        00:11.551   0x1076980   -48 QuartzCore  -[CALayer addAnimation:forKey:]
2   CALayer         Malloc      00:11.552   0x1076980   48  UIKit   -[UIView _createLayerWithFrame:]

深入研究#1 CALayer:

#   Category        Event Type  Timestamp   Address    Size Responsible Library Responsible Caller
0   GeneralBlock-48 Malloc      00:11.470   0x1076980   48  QuartzCore  -[CALayer setDelegate:]
1   GeneralBlock-48 Free        00:11.551   0x1076980   -48 QuartzCore  -[CALayer addAnimation:forKey:]
2   CALayer         Malloc      00:11.552   0x1076980   48  UIKit   -[UIView _createLayerWithFrame:]

好吧,我现在看到,在 #0 或 #1 中更深入地钻取会揭示完全相同的信息。我想这应该可以将故障排除减半......但我仍然不知所措......

【问题讨论】:

  • 您是否尝试过将霰弹枪编程到您的应用程序中?
  • 我走捷径尝试了木桩……唉,它只适用于 NSVampires :-(
  • +1 获取问题的详细信息,以及有趣的标题:D
  • 傻瓜!寻求通用解决方案:圣水!

标签: cocoa cocoa-touch debugging retain


【解决方案1】:

我相信回溯只是僵尸被发送消息的地方。此回溯通常为您提供有关导致崩溃的原因的零信息。它几乎只告诉你被过度释放的对象的类型和地址。

我经常用来追踪这样的过度释放的一种技术是使用 Instruments 的 ObjectAlloc 来追踪所有的保留和释放。在 ObjectAlloc 中找到过度释放对象的地址,然后列出所有的保留/释放调用,然后尝试平衡每个保留与释放。一旦你找到一个没有保留匹配的版本,你就发现了问题。

【讨论】:

  • 抱歉,您如何在 Instruments 中“列出所有保留/释放调用”?
  • 在显示所有分配的表格视图中,单击“* 所有分配 *”旁边的箭头。搜索僵尸CALayer的地址(可以粘贴到下方搜索栏)。单击该地址旁边的箭头。您将看到该地址上所有 malloc/free/retain/release 调用的列表。打开侧边栏以查看每个调用的堆栈跟踪。
  • 谢谢!有帮助!但是当我使用 ObjectAlloc 运行时,NSZombies 不会出现。所以我无法将该地址与列表中的地址进行比较。我相信 Instruments 绕过了 Debugger 以及 XCode 的控制台。啊,我想我刚刚回答了问题的那一部分:查看 Console.app 而不是 XCode 的控制台...
  • 好的,我有两次命中该内存地址。我会把它们放在上面,因为我没有弄清楚......
  • 感谢 kperryua!仪器提供了我识别罪魁祸首所需的线索。有了它和 ObjectAlloc (& Leaks),我能够清理大约六个内存问题。我什至发现了从第一天开始我就在这个应用程序中遇到的一些真正的坏处,尽管它还没有抬起丑陋的头……但是。提示此线程的问题与在子视图的一个实例中不当使用设置器有关。
【解决方案2】:

您可以做的一件快速的事情是在objc_exception_throw 上设置一个符号断点。这将导致您的程序在抛出异常时暂停。这可能无法帮助您确切地找到CALayer 让您感到悲伤,但它应该可以帮助您找到被呼叫的大致附近。

【讨论】:

  • 同意,您需要确切知道发生这种情况的时间。
  • 我启用了 objc_exception_throw 断点,但它对我来说同样神秘。我已经在上面发布了。
  • 这个错误的上下文是什么?你如何处理你的程序来让它着火?从堆栈跟踪来看,它看起来像是在 CA 事务结束时发生的,这意味着可以肯定这是在动画结束时发生的。有动画开火吗?如果是这样,涉及哪些层?你确定retain打算再次使用吗?
  • 使用标准 backBarButtonItem 从详细视图返回表视图时会发生此错误。有问题的详细视图有些复杂,因为它的 VC 有一个包含 3 个子视图的视图。其中两个属于同一类……第三个是不同的。这些子视图中的每一个都有自己的子视图。无论如何,我正在尝试遵循子视图/子视图不保留其父视图的保留/释放规则。除了同一类的两个子视图兄弟之外,一切都很好。如果我将他们的连接分配给父母,我们会遇到这个崩溃。如果我保留它,一切正常,但我们正在泄漏..ARGH!
  • 你能再解释一下吗?我了解您有一个视图控制器,其视图具有三个子视图,其中两个属于同一类。你还说这些视图也有一个父视图——这是你的细节视图控制器吗?细节视图控制器是否保留对两个子视图的引用?
【解决方案3】:

“前面的问题”是警告的一部分,而不是选择器。警告本身来自 NSInvocation,但它提到“class _NSZombie_CALayer”的事实意味着某些东西正在尝试使用已释放的 CALayer。

堆栈跟踪表明当层试图释放其子层时会发生这种情况。

总而言之,这意味着要发布的层有一个子层,该子层已在您的代码中的某处过度发布。检查您的 CALayers 内存管理,或尝试Clang Static Analyzer。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-08
    • 2011-04-22
    • 2015-05-05
    • 2017-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-30
    相关资源
    最近更新 更多