3

我终于明白我是否必须释放一个对象,以及如何在一个简单的应用程序中保持我的保留计数尽可能低(通过知道该对象是否返回一个已经调用的额外“保留”)。因此,NARC 规则在这方面运作良好。

另一方面,我不知道是retain(通常使用保留属性)还是仅使用assign实例变量。那里有经验法则吗?我只知道两个:

  1. 如果我在我的类中创建了实例(例如,在 init 中),那么我应该保留它并在dealloc.
  2. 代表被分配,而不是保留

但我不明白的是我是否应该保留从另一个实例传递过来的东西。我知道风险是保留计数下降到零,我只能拿着袋子(或留下许多额外的袋子和内存),但是......我应该如何组织我的应用程序以免发生这种情况?

我看过一些相关的问题,但没有一般性。

当我在这里时:添加到 aUIWindowUIView我个人不保留的东西怎么办?如果他们的超级视图从所有超级视图中删除,“自然”保留的实例会被释放吗?

4

2 回答 2

10

对于您想要的类类型对象:

  • retain默认情况下
  • copy如果该类来自可变/不可变类集群
  • assign如果你需要弱引用

至于清理,所有retaincopy属性都需要是released.

如果我在我的类中创建了实例(例如,在 init 中),那么我应该保留它并在 dealloc 中释放它。

问题不在于它是否是在您的类的方法中创建的,而在于您是否:

  • 想要一个对实例的强引用
  • 已经拥有它

如果您还没有拥有它并且想要对其进行强引用,请保留 - 这对于传递给您的方法的实例也是如此。无论您是通过 setter 显式还是隐式保留都无关紧要。

于 2010-07-18T21:31:26.650 回答
2

如何使我的保留计数尽可能低

我不明白这一点。是什么让您认为您需要担心保留计数?保留计数是一个实现细节,忘记它。您需要担心的是您是否拥有一个对象。

我不知道是保留(通常使用保留属性)还是只分配实例变量。

在几乎所有情况下,您都希望在分配实例变量时保留或复制。主要的例外是保留周期。有时,您会发现自己处于对象 A 引用对象 B 而对象 B 引用对象 A 的情况。如果 A 保留 B 并且 B 保留 A,则不能依靠在 dealloc 中释放引用的正常模式来使他们走开。在这种情况下,通常将一个对象指定为所有者,将另一个指定为拥有者。然后,拥有的对象将不会保留其对所有者的引用。

这方面的一个例子是一个树结构,其中父节点具有对其子节点的引用,并且每个子节点都有对其父节点的引用。如果每个孩子都保留了它的父母,当应用程序与父母一起完成时,它不会消失,因为它已被所有孩子保留。因此父引用被实现为弱引用,这意味着子引用不保留其父引用。

这是一种非常常见的委托模式,对象的所有者将自己设置为对象的委托。例如,表视图的控制器通常也是表视图的数据源和/或委托。如果表视图保留了委托,您将有一个保留周期(因为控制器已经保留了视图)。这就是为什么出现了“不保留代表”的惯例。

如果您想要引用的对象实现 NSCopying 并且您需要在拥有所有权时不要更改它,则绝对应该复制。Cocoa 的一个例子是 NSDictionary 中元素的键。如果在字典中更改键,那将是一场灾难。所以 NSDictionary 复制它的键。

我知道风险是保留计数下降到零,我只剩下拿着包(或拿着许多额外的包和内存),但是......我应该如何组织我的应用程序以防止这种情况发生?

简单:遵循Cocoa 内存管理规则。如果某物在您持有对它的引用时消失了,那么您并不拥有该东西。如果您需要的东西比当前方法的范围更长,您应该保留它。

于 2010-07-19T08:18:46.200 回答