0

我将 ARC 添加到我正在开发的应用程序中。不幸的是,它崩溃了。我发现将所有应用程序更新到 ARC 的自动脚本为所有 id<protocolName> 类型提供了 __unsafe_unretained 限定符。

  1. 为什么不是弱类型?我已将该应用程序及其所有子项目部署到 iOS 5,因此我的限定符确实很弱。

  2. 我的主要问题是,如果我将这些代表声明为强,我将有一个保留周期。如果我不这样做,下次我打电话给他们时,他们将成为僵尸。我检查并在我的应用程序崩溃之前,代表是 NSZombie。

这次崩溃的原因是什么,如何预防?

4

2 回答 2

0

限定词 __unsafe_unretained 和 week 有很多共同点。例如,它们都不会增加保留计数。例如,如果视图控制器将 __unsafe_unretained IBOutlet 保存到 UIView 并且您从视图层次结构中删除了该 UIView,那么您(假设您没有在其他任何地方保留视图)将减少保留计数并很可能解除分配 UIView . 然而,指针仍将指向该位置并悬空。如果你知道发生了什么,不好,但也没有问题。弱属性通过在对象的保留计数为 0 时使属性无效来帮助您避免悬空指针。

现在,如果您的应用程序崩溃或属性显示为僵尸,那么它们将被释放 - 不管是哪个类。

一种不完全正确的说法是,如果您保留该属性,则会创建一个保留周期。虽然有可能创建保留周期,但这实际上取决于您的实现,而不仅仅是属性声明。当您保留一个对象时,您将获得所有权,并且在您完成该对象之前,通过增加其保留计数来防止它被释放。如果您的委托在您持有弱指针时已经被释放,您不会阻止它被释放。我假设您在这里处理模态视图控制器 - 准确地说是 UIPopoverController(只是猜测)。

您应该使用工具并查看对象的生命周期并查看谁保留/释放它。知道这可能会有所帮助。否则,您可以粘贴一些代码,也许会有一个好人来帮助您找到问题。

欢呼罗尼

于 2014-01-07T21:32:26.247 回答
0

花了一些时间,但我解决了它:

  1. 我将 .xcodeproj 项目部署到 iOS 5,但目标留在 iOS 4.3 部署中。当我修复它时(它位于每个目标的“构建设置”中) - 我可以将所有“__unsafe_unretained”更改为“__weak”,并将所有“unsafe_unretained”更改为“weak”。

  2. 为了避免保留循环,这些代表应该是弱的,它们不再是僵尸(因为它们很弱而不是 unsafe_unretained),并且应用程序不会再崩溃。

如果我仍在使用 iOS4.3-,并且没有 unsafe_unretained 限定符,我应该只在我不再需要它们之后将 nil 分配给这些代表。

于 2014-01-09T07:52:06.260 回答