当我们需要创建一个对象并获得它的所有权时,我们编写
NSObject *someObject = [[NSObject alloc] init];
之后,someObject
保留计数将等于 1。哪种方法会增加计数,alloc
或者init
,以及 Apple 文档中的何处描述了这种行为?
当我们需要创建一个对象并获得它的所有权时,我们编写
NSObject *someObject = [[NSObject alloc] init];
之后,someObject
保留计数将等于 1。哪种方法会增加计数,alloc
或者init
,以及 Apple 文档中的何处描述了这种行为?
之后 someObject 的 retainCounter 将等于 1。问题是哪种方法增加了 retainCounter alloc 或 init 并且在 Apple 文档中描述了这种行为?
“两者都不是”、“两者”或“一个或另一个”都是正确的答案。更好的答案是“这是一个实现细节,您需要关注一般的、非实现依赖的规则”。
首先,抛弃绝对保留计数的概念。这是一种无用的思考方式。
+alloc
返回一个具有 +1 保留计数的对象。返回的任何东西都+alloc
必须在-release
某个地方。实际保留计数是否为 1 完全是一个实现细节,对于 Apple 的许多类而言,它通常不是1。
-init
消耗消息对象的保留计数并产生保留计数 +1 的对象(不是 1,而是“加 1”);返回的结果init
必须是release
d 才能正确管理。
通常情况下,init
只是简单地调用return self;
而不在内部操作保留计数。这保留了上述规则。
但有时它不会,这就是为什么你总是必须self = [super init]
在你的初始化程序中有(当然是检查返回值),以及为什么你永远不应该做类似Foo *f = [Foo alloc]; [f init];
.
该alloc
方法执行实际分配,因此通常*会增加保留计数。init
负责在分配后初始化对象。
*在几个基础类以及第 3 方代码(例如类集群)中存在例外情况,但您始终负责在手动内存管理中调用release
/autorelease
之后调用alloc
嗯,所以有点复杂。对于几乎所有情况,+alloc
增加保留计数,并且对保留计数-init
不做任何事情。
但偶尔,-init
会希望返回一个预先存在的对象而不是初始化alloc
传递给它的空白对象。(NSNumber
例如,这样做。)在这种情况下,-init
将 release self
,然后返回一个具有 +1 保留计数的新对象。
在 ARC 文档中,他们说这-init
是一种“消耗”其接收者并返回保留对象的方法。通常,这只是意味着 init 对保留计数没有任何作用。但有时,-init
其实是在做一些保留。
正如我所说,+alloc
是做保留的人。-init
保证返回一个保留的对象,但在大多数情况下,它本身不做任何保留。