菜鸟教程小白 发表于 2022-12-13 10:35:26

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


                                            <p><p><code>init</code>中ARC下返回<code>nil</code>会导致内存泄漏,当<code></code>已经被调用,然后返回nil?这是合法的用法吗?</p>

<pre><code>- (id)init {
   self = ;
   if (self) {

       ...
       return nil;
       ...

   }
   return self;
}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>首先:对于引用 ARC 的 Q 从未阅读过 Apple 的文档,而是 clang 的。 </p>

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

<pre><code>id ref = [ init]
</code></pre>

<p>你会发现像“<code>+alloc</code> 转移所有权”这样的语句。这至少具有误导性,因为 <code>-init</code> 的返回值而不是 <em></em> <code>+alloc</code> 的返回值被存储。 </p>

<p>到目前为止,clang 的文档更好、更精确。基本上他们说,<code>+alloc</code> 是所有权转移<em>和</em> <code>-init</code> 是所有权消耗和所有权转移。 </p>

<p> <a href="http://clang.llvm.org/docs/AutomaticReferenceCounting.html#semantics-of-init" rel="noreferrer noopener nofollow">http://clang.llvm.org/docs/AutomaticReferenceCounting.html#semantics-of-init</a> </p>

<blockquote>
<p>Methods in the init family implicitly consume their self parameter and return a retained object. </p>
</blockquote>

<p>那么让我们看一下通常的代码:</p>

<pre><code>id ref = ;
// ref is strong: RC is +1;
id ref = ;   
// 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
</code></pre>

<p>结果是该对象的 RC 为 +1,并且您在该代码区域中有一个对它的强引用。一切都很好。 (当然有很大的优化潜力,因为在大多数情况下 <code>self</code> 和 <code>ref</code> 都没有改变,但让我们保持正常的轨道。)</p>

<p>让我们在 <code>-init</code> 中更改 <code>self</code>:</p>

<pre><code>id ref = ; // Ownership transfer. RC is +1;
id ref = ;   
// 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&#39;s return nil as in your example
    return nil;
    // Because nil is returned, virtually the RC of nil is increased. self&#39;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.
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 在 init 中返回 nil 会导致内存泄漏吗?,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/29603467/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/29603467/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 在 init 中返回 nil 会导致内存泄漏吗?