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

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

[super init]已经被调用,然后返回nil时,在init中的ARC下返回nil会导致内存泄漏吗?这是合法的用法吗?

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

       ...
       return nil;
       ...

   }
   return self;
}

最佳答案

首先:对于涉及 ARC 的 Q,从来没有阅读过 Apple 的文档,而是 clang 的文档。

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

id ref = [[Class alloc] init]

您会发现有一条类似“+alloc 转移所有权”的语句。这至少会产生误导,因为存储的是 auf -init 的返回值,而不是 +alloc 的返回值。

clang 的文档到目前为止更好、更精确。基本上他们说,+alloc 是所有权转移-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.

让我们看一下常用的代码:

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 都没有改变,但让我们保持常规轨道。)

让我们在 -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.

关于ios - init中返回nil会导致内存泄漏吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29603467/

相关文章:

c++ - XCode 和 _bittest 函数

C - 锯齿波的傅立叶变换级数

ios - 即使队列中有项目,skipPrevious 和 skipNext 按钮也无效 Google Cast iOS Sender SDK v4.3.5 及更高版本

ios - 调用并添加到 UIScrollview 时未设置自定义 UIView 类的属性

ios - Objective-c 负十六进制值

objective-c - 显示占位符文本

sql-server - 如何将 .bacpac 导入 docker Sqlserver?

iphone - 如何从底部对齐 UILabel 文本?

ios - 在 iOS 上的任何其他应用程序之上弹出的应用程序

python - 在 Python 中为 Mac 创建一个 MessageBox?