iphone – 为什么使用ARC NSZombieEnabled时对象不会释放

我将我的应用程序转换为ARC,并注意到在我的一个视图控制器中分配的对象在视图控制器被释放时并没有被释放。花了一些时间来弄清楚为什么。我有启用Zombie对象为我的项目调试,这是原因。考虑以下应用程序逻辑:

1)用户调用RootViewController中的操作,导致通过presentModalViewController创建和呈现SecondaryViewController:animated。

2)SecondaryViewController包含一个ActionController,它是一个NSObject子类。

3)ActionsController在初始化时通过NSNotificationCenter观察通知,并在解除分配时停止观察。

4)用户关闭SecondaryViewController以返回到RootViewController。

启用Zombie对象关闭,上面的工作正常,所有对象被释放。启用Zombie对ActionsController的对象不会释放,即使SecondaryViewController被释放。

这导致我的应用程序中的问题b / c NSNotificationCenter继续向ActionsController发送通知,并且生成的处理程序导致应用程序崩溃。

我创建了一个简单的应用程序说明这在https://github.com/xjones/XJARCTestApp.查看控制台日志与启用Zombie对象开/关验证这一点。

问题(S)

>这是启用僵尸对象的正确行为吗?
>我应该如何实现这种类型的逻辑,以消除这个问题。我想继续使用启用Zombie对象。

编辑#1:根据Kevin的建议,我已经提交这个到苹果和openradar在http://openradar.appspot.com/10537635

编辑#2:澄清一个好的答案

首先,我是一个有经验的iOS开发者,我完全理解ARC,僵尸对象等。如果我错过了一些东西,当然,我喜欢任何照明。

其次,确实,这种特定崩溃的解决方法是在secondaryViewController被释放时将actionsController作为观察者删除。我还发现,如果我明确设置actionsController = nil当secondaryViewController被释放时,它将被dealloc’ed。这两个都不是很大的解决方法b / c他们有效地要求你使用ARC,但代码,如果你没有使用ARC(例如nil iVars明确地在dealloc)。一个特定的解决方案也没有帮助识别这将是其他控制器中的问题,因此开发人员知道何时/如何解决这个问题的确定性。

一个好的答案会解释如何确定性地知道,当使用ARC NSZombieEnabled时,你需要做一些特殊的事情,所以它会解决这个具体的例子,也适用于一个项目作为一个整体w / o留下潜在的其他类似的问题。

完全可能的是,不存在一个好的答案,因为这可能是XCode中的错误。

感谢所有!

最佳答案
原来,我写了一些严重的废话

如果僵尸像我原来写的,打开僵尸会直接导致无数的误报…

有一些isa-swizzling继续,可能在_objc_rootRelease,所以任何覆盖dealloc应该仍然使用zombies启用调用。唯一不会发生在僵尸的事情是对object_dispose的实际调用 – 至少不是默认情况下。

有趣的是,如果你做一个小日志记录,你会看到,即使启用了ARC,你的dealloc的实现将调用它的超类的实现。

我实际上假设没有看到这一点:因为ARC生成这些时髦的.cxx_destruct方法来处置类的任何__strong的ivar,我期待看到这个方法调用dealloc – 如果它被实现。

显然,将NSZombieEnabled设置为YES会导致.cxx_destruct不被调用 – 至少这是我编辑你的示例项目时发生了什么:
僵尸关闭导致backtrace和两个deallocs,而僵尸不产生backtrace和只有一个dealloc。

如果你有兴趣,额外的日志包含在a fork of the sample project – 工作通过运行:有两个共享方案僵尸开/关。

原始(无意义)答案:

这不是一个错误,而是一个功能。

它与ARC无关。

NSZombieEnabled基本上swizzles dealloc为一个实现,反过来,isa-swizzles对象的类型为_NSZombie – 一个虚假的类,一旦你发送任何消息,它就会爆炸。这是预期的行为和 – 如果我没有完全错误 – 记录。

转载注明原文:iphone – 为什么使用ARC NSZombieEnabled时对象不会释放 - 代码日志