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

ios - 防止retain-cycle的两种阻塞方式


                                            <p><p>如果可能存在保留周期,我通常使用这样的 block :</p>

<pre><code>- (void)someFunction {
    __weak __typeof(self) weakSelf = self;
    [self setHandler:^{
      ;
    }];
}
</code></pre>

<p>但最近我看到了另一种方式:</p>

<pre><code>- (void)someFunctionWithParam:(id)param {
    __weak __typeof(param) weakParam = param;
    [self setHandler:^{
      __typeof(weakParam) strongParam = weakParam;
      ;
    }];
}   
</code></pre>

<p>它们有什么区别?</p>

<p>Edit1:这是否意味着 <code>self</code> 运行处理程序时 <code>param</code> 不会被释放?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>在第二个示例中,在特定情况下创建 <code>strongSelf</code> 变量没有任何好处,但我可以向您展示一个有好处的示例。</p>

<p>在第一个示例中,语句 <code></code> 加载 <code>weakSelf</code> 中的引用,保留它,发送 <code>doSomething</code> 消息,然后然后(在 <code>doSomething</code> 返回之后)释放引用。第二个示例“手动”执行基本完全相同的步骤。</p>

<p>这里有一个稍微不同的例子:</p>

<pre><code>- (void)someFunction {
    __weak __typeof(self) weakSelf = self;
    [self setHandler:^{
      ;
      ;
    }];
}
</code></pre>

<p>在我的代码中,假设在调用 block 时只有一个对 <code>self</code> 对象的强引用。 <code></code> 语句创建第二个对它的临时强引用。当 <code>doSomething</code> 运行时,另一个线程释放另一个强引用。当 <code>doSomething</code> 返回时,该语句将释放其临时强引用。现在 <code>self</code> 没有更多的强引用,所以它被释放并且 <code>weakSelf</code> 被设置为 nil。</p>

<p>然后 <code></code> 语句运行。它想加载并保留 <code>weakSelf</code> 的内容,但由于 <code>weakSelf</code> 现在为 nil,该语句只使用 nil。它将 <code>doAnotherThing</code> 消息发送到 nil,这是允许的并且不会崩溃。它什么也不做。它不调用该方法。</p>

<p>这可能不是您想要的行为。如果 <code>doSomething</code> 运行,您可能<strong>总是</strong>希望 <code>doAnotherThing</code> 在 <code>self</code> 上运行。那是您需要第二个示例中的模式的时候:</p>

<pre><code>- (void)someFunctionWithParam:(id)param {
    __weak __typeof(self) weakSelf = self;
    [self setHandler:^{
      __typeof(weakSelf) strongSelf = weakSelf;
      ;
      ;
    }];
}   
</code></pre>

<p>这里,当 block 被调用时,它会立即在 <code>strongSelf</code> 中存储对 <code>self</code> 的强引用(或者如果 <code>weakSelf</code> 有则存储 nil已经设置为零)。 <code>strongSelf</code> 引用直到最后一次使用 <code>strongSelf</code> 变量后才能释放,因此 <code>self</code> 不可能在 <code> 之后被释放>doSomething</code> 但在 <code>doAnotherThing</code> 之前。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 防止retain-cycle的两种阻塞方式,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/37825148/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/37825148/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 防止retain-cycle的两种阻塞方式