我正在阅读Xcode的文档,这里有一些让我感到困惑的东西:
__block typeof(self) tmpSelf = self;
[self methodThatTakesABlock:^ {
[tmpSelf doSomething];
}];
以下内容摘自文档:
块形成对它捕获的变量的强引用。如果在块中使用
self
,则该块将形成对self
的强引用,因此如果self
也具有对该块的强引用(通常如此),则会导致强引用循环。为了避免这个循环,您需要在代码块之外创建一个对self的弱(或__block
)引用,如上面的示例所示。
我不明白‘弱(或__block
)’是什么意思?
是
__block typeof(self) tmpSelf = self;
和
__weak typeof(self) tmpSelf = self;
这里完全一样吗?
我在文档中发现了另一块:
注意:在垃圾收集环境中,如果对变量同时应用
__weak
和__block
修饰符,则该块将不能确保它保持活动状态。
所以,我完全迷惑了。
发布于 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,并且可能会给您留下挂起的指针。
发布于 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以中断保留循环。
发布于 2018-01-26 16:58:23
除了关于__block
与__weak
的其他答案之外,还有另一种方法可以在您的场景中避免保留周期。
@weakify(self);
[self methodThatTakesABlock:^ {
@strongify(self);
[self doSomething];
}];
https://stackoverflow.com/questions/11773342
复制相似问题