首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >__weak和__block引用之间的区别是什么?

__weak和__block引用之间的区别是什么?
EN

Stack Overflow用户
提问于 2012-08-02 16:02:58
回答 4查看 31.3K关注 0票数 80

我正在阅读Xcode的文档,这里有一些让我感到困惑的东西:

代码语言:javascript
复制
__block typeof(self) tmpSelf = self;
[self methodThatTakesABlock:^ {
    [tmpSelf doSomething];
}];

以下内容摘自文档:

块形成对它捕获的变量的强引用。如果在块中使用self,则该块将形成对self的强引用,因此如果self也具有对该块的强引用(通常如此),则会导致强引用循环。为了避免这个循环,您需要在代码块之外创建一个对self的弱(或__block)引用,如上面的示例所示。

我不明白‘弱(或__block)’是什么意思?

代码语言:javascript
复制
__block typeof(self) tmpSelf = self;

代码语言:javascript
复制
__weak typeof(self) tmpSelf = self;

这里完全一样吗?

我在文档中发现了另一块:

注意:在垃圾收集环境中,如果对变量同时应用__weak__block修饰符,则该块将不能确保它保持活动状态。

所以,我完全迷惑了。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-08-02 16:19:25

来自关于__block的文档

__block变量存储在变量的词法作用域和在该变量的词法作用域中声明或创建的所有块和块副本之间共享的存储器中。因此,如果在帧中声明的块的任何副本在帧的结尾之外存活(例如,通过在某处排队以供稍后执行),则存储将在堆栈帧的破坏中幸存下来。给定词法作用域中的多个块可以同时使用一个共享变量。

来自关于__weak的文档

__weak指定的引用不会使被引用的对象保持活动状态。当没有对对象的强引用时,弱引用被设置为nil。

所以从技术上讲,它们是不同的东西。__block用于停止将变量从外部作用域复制到块作用域。__weak是一个自定界弱指针。

注意,我说的是技术上的,因为对于你的情况,他们(几乎)会做同样的事情。唯一的区别是你是否在使用ARC。如果您的项目使用ARC,并且仅适用于is 4.3及更高版本,请使用__weak。如果全局作用域引用以某种方式被释放,它将确保引用被设置为nil。如果您的项目不使用ARC或用于较旧的操作系统版本,请使用__block。

这里有一个细微的区别,请确保你理解它。

编辑:另一块拼图是__unsafe_unretained。此修饰符与__weak几乎相同,但适用于4.3版之前的运行时环境。但是,它没有被设置为nil,并且可能会给您留下挂起的指针。

票数 109
EN

Stack Overflow用户

发布于 2013-07-31 16:32:48

在手动引用计数模式下,__block id x;具有不保留x的效果。在ARC模式下,__block id x;默认为保留x(就像所有其他值一样)。要获得ARC下的手动引用计数模式行为,您可以使用__unsafe_unretained __block id x;。然而,顾名思义,使用非保留变量是危险的(因为它可能会悬空),因此不鼓励使用非保留变量。两个更好的选择是使用__weak (如果您不需要支持iOS 4或OS X v10.6),或者将__block值设置为nil以中断保留循环。

apple docs

票数 5
EN

Stack Overflow用户

发布于 2018-01-26 16:58:23

除了关于__block__weak的其他答案之外,还有另一种方法可以在您的场景中避免保留周期。

代码语言:javascript
复制
@weakify(self);
[self methodThatTakesABlock:^ {
    @strongify(self);
    [self doSomething];
}];

More Info about @Weakify @Strongify Macro

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11773342

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档