[英]Will returning nil in init cause a memory leak?
Will returning nil
under ARC in init
lead to memory leak, when [super init]
was already called, but then returned nil? 在已经调用[super init]
但又返回nil
下,在init
ARC下返回nil
会导致内存泄漏吗? Is this a legit usage? 这是合法用法吗?
- (id)init {
self = [super init];
if (self) {
...
return nil;
...
}
return self;
}
First of all: For Qs referring to ARC never read Apple's documentation, but clang's. 首先:关于Q的ARC从来没有阅读过Apple的文档,而是从clang的文档。
Apple's documentation simply conceals (concealed?) the execution of -init
and have wrong examples like that: Apple的文档仅隐藏(隐藏?)- -init
的执行,并具有如下错误的示例:
id ref = [[Class alloc] init]
You will find there a statement like " +alloc
transfers ownership". 您会在此处找到类似“ +alloc
transfers +alloc
”的语句。 This is at least misleading, because the return value auf -init
and not the return value of +alloc
is stored. 这至少具有误导性,因为存储了返回值auf -init
而不是 +alloc
的返回值。
clang's documentation is better and more precise by far. 到目前为止,clang的文档更好,更精确。 Basically they say, that +alloc
is an ownership transfer and that -init
is ownership consuming and ownership transferring. 他们基本上说, +alloc
是所有权转移,而-init
是所有权消耗和所有权转移。
http://clang.llvm.org/docs/AutomaticReferenceCounting.html#semantics-of-init http://clang.llvm.org/docs/AutomaticReferenceCounting.html#semantics-of-init
Methods in the init family implicitly consume their self parameter and return a retained object. 初始化族中的方法隐式使用其自身参数并返回保留的对象。
So let's have a look to the usual code: 因此,让我们看一下通常的代码:
id ref = [Class alloc];
// ref is strong: RC is +1;
id ref = [ref init];
// Three things happen her:
// 1. -init is executed
// 2. The new value is stored
// 3. The old value of ref is lost
// 1. -init is executed
// self is (silently) passed to the receiver
- (id)init
{
// Since self is strong (+1), RC is +2 now
// Since -init is ownership consuming (-1), RC is +1 now
…
return self;
// Since -init is ownership transferring (+1), RC is +2 now
}
// 2. The new value is stored
// The value comes from an ownership transfer method, so the assignment to strong ref is neutral (0), RC is still +2
// 3. The old value is lost (-1), RC is +1
The result is that the object has an RC of +1 and you have one strong reference to it in that code area. 结果是该对象的RC为+1,并且您在该代码区域中对其有一个强大的引用。 Everything is fine. 一切顺利。 (Of course there is a high potential for optimization, because in most cases neither self
nor ref
is changed, but let's keep on the regular track.) (当然,有很大的优化潜力,因为在大多数情况下, self
和ref
都不会改变,但让我们保持常规。)
Let's change self
inside -init
: 让我们在-init
内部更改self
:
id ref = [Class alloc]; // Ownership transfer. RC is +1;
id ref = [ref init];
// Three things happen her:
// 1. -init is executed
// 2. The new value is stored
// 3. The old value of ref is lost
// 1. -init is executed
// self is (silently) passed to the receiver
- (id)init
{
// Since self is strong (+1), RC is +2 now
// Since -init is ownership consuming (-1), RC is +1 now
// Let's return nil as in your example
return nil;
// Because nil is returned, virtually the RC of nil is increased. self's RC == +1 is unchanged.
}
// 2. The new value is stored
// The new value is nil.
// However the value comes from an ownership transfer method, so the assignment to strong ref is neutral (0), RC is still +1
// 3. The old value is lost (your old ref and the self while executing -init) (-1), RC is 0
// The old object is dealloced, if you do not have another ref to it. Nothing leaks.
我只是在乐器中检查过-没有内存泄漏
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.