Cocoa NSZombies正在吃掉我的应用程序';这是我的大脑!

Cocoa NSZombies正在吃掉我的应用程序';这是我的大脑!,cocoa,cocoa-touch,debugging,retain,Cocoa,Cocoa Touch,Debugging,Retain,我有一个保留/释放问题。我的视图非常复杂,所以我将NSZombieEnabled设置为YES,并试图找到到底是哪个对象引起了我的悲伤。为了加快这一过程,我想知道是否有线索或技巧可以追踪僵尸回到他们挖出的坟墓(抱歉,不得不这么做),或者,回到与他们相关的物体?神秘的控制台消息似乎没有提供太多的见解: NSInvocation: warning: object 0x1076850 of class '_NSZombie_CALayer' does not implement methodSignat

我有一个保留/释放问题。我的视图非常复杂,所以我将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一般块-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层:

#   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号钻得更深揭示了完全相同的信息。我想这应该可以将故障排除过程减少一半…但我仍然不知所措…

您可以做的一件简单的事情是在
objc\u exception\u throw
上设置一个符号断点。这将导致程序在抛出异常时暂停。这也许不能帮助你准确地追踪到底是哪个CALayer给你带来了悲伤,但它应该能帮助你找到它被调用的大致位置。

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


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

前面的故障是警告的一部分,而不是选择器。警告本身来自NSInvocation,但它提到“class\u NSZombie\u CALayer”这一事实意味着有东西试图与已解除分配的CALayer一起工作

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


总之,这意味着要发布的层在代码中的某个地方有一个子层被过度发布。检查CALayers的内存管理,或者尝试。

同意,您需要确切地知道这是什么时候发生的。我启用了objc_异常_抛出断点,但对我来说它同样神秘。我已经在上面发布了。这个错误的背景是什么?你如何使用你的程序使它启动?从堆栈跟踪来看,它看起来像是发生在CA事务的末尾,这意味着这是一个安全的赌注,它将发生在动画的末尾。有动画发射吗?如果是,涉及哪些层?是否确保保留要再次使用的视图?使用标准BackbarButtonim从详细视图返回表视图时,会发生此错误。所讨论的细节视图有些复杂,因为它的VC有一个包含3个子视图的视图。其中两个属于同一类……第三个不同。每个子视图都有自己的子视图。无论如何,我试图遵循保留/释放规则,其中子视图/子视图不保留其父视图。除了同一类的两个子视图同级之外,其他所有子视图都可以正常工作。如果我将它们的连接分配给父级,我们将得到此崩溃。如果我保留它的话,事情会好起来的,但我们正在泄漏..啊!你能再解释一下吗?我知道您有一个视图控制器,其视图有三个子视图,其中两个子视图属于同一类。您还说过这些视图也有父视图--这是您的详细视图控制器吗?细节视图控制器是否保留了对这两个子视图的引用?您是否尝试过将散弹枪编程到您的应用程序中?我走了一条捷径,尝试了木桩……唉,这只适用于NSVampiles:-(+1了解问题的细节,有趣的标题是:DFools!使用通用解决方案:圣水!抱歉,您怎么做在Instruments中“列出所有保留/释放调用”在显示所有分配的tableview中,单击“*所有分配*”旁边的箭头。搜索僵尸CALayer的地址(您可以将其粘贴到下面的搜索字段中)。单击该地址旁边的箭头。您将看到该地址上所有malloc/free/retain/release调用的列表。打开侧栏以查看每个调用的堆栈跟踪。谢谢!非常有用!但是当我使用ObjectAlloc运行时,NSZombies不会显示。因此我无法将该地址与列表中的地址进行比较。我相信工具可以绕过Debugger和XCode的控制台。啊,我想我刚刚回答了问题的这一部分:在console.app中查找,而不是XCode的控制台…好的,我有两个关于该内存地址的点击。我将把它们放在上面,因为我没有弄清楚这一点…谢谢kperryua!Instruments为我提供了识别罪犯所需的线索。有了这些和ObjectAlloc(&Leaks)我能够清理大约六个内存问题。我甚至发现了一些从第一天起我在这个应用程序中遇到的真正的不好的地方,尽管它还没有抬起它丑陋的头…但是。引发这个线程的问题与在子视图的一个实例中不正确地使用setter有关。