在Objective-C的代码块中,我们是否需要使用weak self?

4

我注意到苹果文档中提到需要避免强引用循环,当使用self时。

在示例中,该块是self的一个属性。

但是如果我将块作为dispatch_async语句中的局部变量放置呢?

在这种情况下,即使直接调用self的方法,也不会创建保留循环,对吧?

以下代码是否需要生成weakSelf,见此文章

// your code
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
    __strong typeof(weakSelf) strongSelf = weakSelf;
    if (strongSelf) {
        [strongSelf doThis];
        [strongSelf doThat];
        [Manager.sharedInstance updateSuccessCount];
    }
});

// more code

2
使用相关代码更新您的问题。 - rmaddy
@rmaddy 你好,我已经在这里更新了代码。 - Yao Fan
@RaphaelSchweikert 谢谢,我同意你的观点。我刚刚更新了问题,并附上了一些示例代码。 - Yao Fan
仅供参考,上面的代码并不能保证 strongSelf 是有效的。如果在赋值语句之前 weakSelf 变为 nil,则 strongSelf 也将为 nil。strongSelf 在此处保证的是它将在该代码块的其余部分中成为一个有效的对象或者是 nil。如果您想要确保对象是非 nil 的,请将 strongSelf 声明放在 if 语句之前,并检查 strongSelf 是否为 nil。 - Lucas Derraugh
我更新了问题中的代码,修复了那个似乎与所提出的问题无关的错误,以防有人复制它。 - malhal
显示剩余2条评论
1个回答

6
在上面的示例中,使用 dispatch_async,不会出现保留循环,因此在这里强引用捕获 self 是安全的。唯一的区别是,如果在调用此 dispatch_async 和块实际运行之间,其他所有内容都已释放了 self,那么它稍微会延迟 self 的实际释放时间,并且可能也会影响释放发生的线程。但通常情况下,在使用 dispatch_async 时,两种方式都无害。

您可能希望像上面示例中编写代码的方式的一个案例是,如果在块中运行的代码有点昂贵,并且只有在绝对必要时才需要执行,那么就不必要执行,因为 self 已经被全部释放。

另一种情况可能是,self 使用大量内存,并且正好在其他东西开始消耗大量内存之前正常释放。在这种情况下,您可能不希望同时分配这两个实例。


好的,知道了。我同意你的观点。谢谢。 - Yao Fan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接