4

当我们需要创建一个对象并获得它的所有权时,我们编写

NSObject *someObject = [[NSObject alloc] init];

之后,someObject保留计数将等于 1。哪种方法会增加计数,alloc或者init,以及 Apple 文档中的何处描述了这种行为?

4

3 回答 3

12

之后 someObject 的 retainCounter 将等于 1。问题是哪种方法增加了 retainCounter alloc 或 init 并且在 Apple 文档中描述了这种行为?

“两者都不是”、“两者”或“一个或另一个”都是正确的答案。更好的答案是“这是一个实现细节,您需要关注一般的、非实现依赖的规则”。

首先,抛弃绝对保留计数的概念。这是一种无用的思考方式。

+alloc返回一个具有 +1 保留计数的对象。返回的任何东西都+alloc必须在-release某个地方。实际保留计数是否为 1 完全是一个实现细节,对于 Apple 的许多类而言,它通常不是1。

-init消耗消息对象的保留计数并产生保留计数 +1 的对象(不是 1,而是“加 1”);返回的结果init必须是released 才能正确管理。

通常情况下,init只是简单地调用return self;而不在内部操作保留计数。这保留了上述规则。

但有时它不会,这就是为什么你总是必须self = [super init]在你的初始化程序中有(当然是检查返回值),以及为什么你永远不应该做类似Foo *f = [Foo alloc]; [f init];.

于 2012-04-20T22:18:11.827 回答
11

alloc方法执行实际分配,因此通常*会增加保留计数。init负责在分配后初始化对象。

*在几个基础类以及第 3 方代码(例如类集群)中存在例外情况,但您始终负责在手动内存管理中调用release/autorelease之后调用alloc

于 2012-04-20T21:05:53.397 回答
5

嗯,所以有点复杂。对于几乎所有情况,+alloc增加保留计数,并且对保留计数-init不做任何事情。

但偶尔,-init会希望返回一个预先存在的对象而不是初始化alloc传递给它的空白对象。(NSNumber例如,这样做。)在这种情况下,-init将 release self,然后返回一个具有 +1 保留计数的新对象。

在 ARC 文档中,他们说这-init是一种“消耗”其接收者并返回保留对象的方法。通常,这只是意味着 init 对保留计数没有任何作用。但有时,-init其实是在做一些保留。

如果这让您感到困惑,请不要担心。

正如我所说,+alloc是做保留的人。-init保证返回一个保留的对象,但在大多数情况下,它本身不做任何保留。

于 2012-04-20T21:17:32.227 回答