NSZombies正在吃我的应用程序的大脑!

时间:2009-07-29 08:21:22

标签: cocoa cocoa-touch debugging retain

我有保留/释放问题。我的视图非常复杂,所以我将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深度钻探显示完全相同的信息。我想这应该减少一半的故障排除...但我仍然不知所措......

3 个答案:

答案 0 :(得分:6)

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

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

答案 1 :(得分:2)

您可以做的一件事就是在objc_exception_throw上设置一个符号断点。这将导致程序在抛出异常时暂停。这可能无法帮助您追踪完全哪个CALayer让您感到悲伤,但它应该可以帮助您找到被调用的一般附近区域。

答案 2 :(得分:2)

“麻烦未来”是警告的一部分,而不是选择器。警告本身来自NSInvocation,但它提到“class _NSZombie_CALayer”的事实意味着某些东西正在尝试使用已被解除分配的CALayer。

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

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