在init中返回nil会导致内存泄漏吗?

时间:2015-04-13 10:47:48

标签: ios objective-c macos cocoa automatic-ref-counting

nil的ARC下返回init会导致内存泄漏,而[super init]已被调用,但之后返回nil?这是合法用法吗?

- (id)init {
   self = [super init];
   if (self) {

       ...
       return nil;
       ...

   }
   return self;
}

2 个答案:

答案 0 :(得分:4)

首先:对于提到ARC的Q,从不读Apple的文档,而是铿锵的。

Apple的文档只是隐藏(隐藏?)-init的执行,并且有错误的例子:

id ref = [[Class alloc] init]

您会在那里找到类似“+alloc转让所有权”的声明。这至少具有误导性,因为存储了返回值auf -init +alloc的返回值。

到目前为止,clang的文档更好,更精确。基本上他们说,+alloc是所有权转移-init是所有权消费和所有权转移。

http://clang.llvm.org/docs/AutomaticReferenceCounting.html#semantics-of-init

  

init系列中的方法隐式使用其self参数并返回保留的对象。

让我们来看看通常的代码:

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

结果是该对象的RC为+1,并且您在该代码区域中有一个强引用。一切都好。 (当然,优化的可能性很大,因为在大多数情况下,selfref都没有改变,但让我们保持常规轨道。)

让我们更改self内的-init

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.

答案 1 :(得分:0)

我刚在仪器中检查过 - 没有内存泄漏