6

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

4

3 回答 3

6

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

A technique I often use to track down over-releases like this is to use Instruments' ObjectAlloc to track all retains and releases. Find the address for the over-released object in ObjectAlloc, then list all the retain/release calls, and then try to balance each retain with a release. Once you find a release without a retain to match, You've found the problem.

于 2009-07-29T18:23:43.140 回答
2

您可以做的一件快速的事情是在objc_exception_throw. 这将导致您的程序在抛出异常时暂停。这可能无法帮助您准确找出让CALayer您感到悲伤的原因,但它应该可以帮助您找到被调用的大致附近。

于 2009-07-29T13:43:03.160 回答
2

“trouble ahead” is part of the warning, not the selector. The warning itself comes from NSInvocation, but the fact that it mentions “class _NSZombie_CALayer” means that something’s trying to work with a CALayer that’s been dealloced.

The stack trace indicates that this is happening when a layer is trying to release its sublayers.

Altogether, this means that the layer being released has a sublayer that has been over-released somewhere in your code. Check your memory management of CALayers, or try the Clang Static Analyzer.

于 2009-07-29T18:56:49.783 回答