拥有您创建的对象

时间:2015-05-28 11:50:18

标签: ios objective-c memory-management

我知道有很多次讨论,但我在研究内存管理方面一度感到困惑。

它表示,您拥有对象的所有权,您可以使用alloc / copy / new / mutableCopy或类似allocWithSomething的方法创建。

但是,当您在ARC中创建NSArray *arr = [NSArray array];之类的对象时,它等同于写NSArray *arr = [[NSArray array]autorelease];

但是,我看到很多次声明 - 你拥有你创建的每个对象。但在上面的情况中,我们实际上并不拥有对象,我们只是将其添加到autorelease pool。因此,我们不必保留/释放它,并且一旦它离开功能范围就会消失(正如Apple所说,在#34;事件后#34;)。

请你澄清那个时刻,我们真的拥有我们创建的每个对象,还是只有使用alloc / copy / mutableCopy / new创建的对象,因此将保留计数增加+1?

3 个答案:

答案 0 :(得分:1)

这是Objective-C中所有权术语的问题。最简单的规则是,如果在完成对象之后必须释放对象,我们将拥有该对象。所以从一个所有者开始可能是一个类,可能是一个方法或一个函数,甚至一个块,仍然有更多。同一个对象可能有多个所有者。

可以通过release方法或autorelease方法调用此版本。我们将它添加到自动释放池中以延迟其释放,直到池被耗尽,这在大多数情况下在runloop的末尾。您发布的代码与[[NSArray array]autorelease];错误,因为这会因为过度释放而导致您的应用崩溃。正确的版本是[[NSArray new] autorelease];,这或多或少是静态方法array返回的。

因此,如果我们暂时排除autorelease,我们会有3个元素:retain将获取对象的所有权并增加保留计数,同时也会强制您在某个时候释放它;如果保留计数降为零(调用者是最后一个所有者),release将放弃所有权,减少保留计数并可能释放对象;对象创建规则说包含create,alloc,new,copy ...的所有方法或函数都会在不保留所有权的情况下为您提供所有权,并且您有责任明确调用它们的发布。

创建对象时,其保留计数为1.这意味着我们称之为alloc + init或其中任何版本的每个对象的保留计数均为1且需要为明确发布。所有其他静态方法(例如[NSArray array])仅仅是[[[NSArray alloc] init] autorelease]的便利,需要保留这些方法才能接管所有权。

所以基本上如果你有一个具有数组指针NSArray *_array的类,并且我们想要获得所有权,我们必须编写_array = [someArray retain]并且在dealloc方法中我们必须编写{{ 1}}。如果某个方法需要获取所有权,我们需要调用[_array release],当我们完成后,我们需要调用[someArray retain],除非我们返回对象本身,我们需要调用[someArray release]。这些是非常简单的规则,但是其他一些情况使得跟踪非常困难。那么ARC的作用是它在代码中为您插入这些调用,您无需担心它们。仍然存在与ARC之前相同的程序。

那么ARC如何准确地插入这些调用并没有真正解释并且与版本不同。但是,如果我们再看一下您再次发布的示例,请让我们扩展它:

return [someArray autorelease]

答案 1 :(得分:1)

这可能会大大过分简化,但是当您调用[NSArray数组]时,实际上并没有请求内存空间,NSArray类正在为您执行此操作。 NSArray类有一个看起来像这样的方法:

  + (NSArray *) array
  {
      return [[[NSArray alloc] init] autorelease];
  }

所以它创建了对象并“拥有”它,而不是你。

对于它的价值,而不是“拥有”,我更愿意将其视为“负责”。如果使用alloc和类似方法为对象请求内存,那么您负责释放该内存。

答案 2 :(得分:1)

您拥有自己创建的每个对象 - 只要您想拥有它。 “拥有”意味着您持有对象的保留计数,并且您将释放保留计数,或将责任和所有权传递给其他人。

[[NSArray alloc] init...]

创建一个您当时拥有的对象,保留计数为1.您可以将该对象传递给接管所有权的其他人。

[NSArray array]

创建并返回一个对象,但会立即将其添加到自动释放池中。返回时,该对象不归任何人所有;自动释放池只是防止它被解除分配,直到自动释放池本身消失。任何愿意的人都可以拥有该对象的所有权。当然,不止一位代码可以获得对象的所有权。当每个人都释放所有权,并且自动释放池也消失时,该对象将消失。

无论如何,ARC将为您处理所有这些事情。