我将我的应用程序转换为 ARC,并注意到当视图控制器被释放时,在我的视图控制器之一中分配的对象没有被释放。我花了一段时间才弄清楚原因。我在调试时为我的项目启用了“启用僵尸对象”,结果证明这就是原因。考虑以下应用程序逻辑:
1)用户调用actionRootViewController
这会导致SecondaryViewController
通过创建和呈现presentModalViewController:animated
.
2) SecondaryViewController
包含一个ActionsController
那是一个NSObject
子类。
3) ActionsController
通过观察通知NSNotificationCenter
当它被初始化并在它被释放时停止观察。
4)用户拒绝SecondaryViewController
返回到RootViewController
.
关闭启用僵尸对象后,上述工作正常,所有对象都被释放。启用“启用僵尸对象”ActionsController
即使没有被释放SecondaryViewController
被解除分配。
这导致我的应用程序 b/c 出现问题NSNotificationCenter
继续发送通知至ActionsController
生成的处理程序会导致应用程序崩溃。
我创建了一个简单的应用程序来说明这一点https://github.com/xjones/XJARCTestApp https://github.com/xjones/XJARCTestApp。查看控制台日志并打开/关闭“启用僵尸对象”以验证这一点。
问题)
- 这是启用僵尸对象的正确行为吗?
- 我应该如何实现这种逻辑来消除这个问题。我想继续使用启用僵尸对象。
编辑 #1:根据 Kevin 的建议,我已将其提交给 Apple 和 openradarhttp://openradar.appspot.com/10537635 http://openradar.appspot.com/10537635.
编辑#2:澄清一个好的答案
首先,我是一名经验丰富的 iOS 开发人员,我完全了解 ARC、僵尸对象等。如果我遗漏了什么,当然,我很感激任何启发。
其次,确实,此特定崩溃的解决方法是删除actionsController
作为观察者,当secondaryViewController
被解除分配。我还发现,如果我明确设置actionsController = nil
when secondaryViewController
is dealloc'ed 它将被dealloc'ed。这两种方法都不是很好的解决方法,因为它们实际上要求您使用 ARC,但编码就好像您没有使用 ARC(例如,在 dealloc 中显式设置 nil iVars)。特定的解决方案也无助于确定其他控制器中何时会出现此问题,因此开发人员可以确定地知道何时/如何解决此问题。
一个好的答案将解释如何确定性地知道在使用 ARC + NSZombieEnabled 时需要对对象做一些特殊的事情,这样它就可以解决这个特定的示例,并且通常也适用于整个项目,而不会留下其他类似的可能性问题。
完全有可能不存在一个好的答案,因为这可能是 XCode 中的一个错误。
谢谢大家!