__weak和__block引用有什么区别?
我正在阅读Xcode的文档,这里是让我感到困惑的东西:
__block typeof(self) tmpSelf = self; [self methodThatTakesABlock:^ { [tmpSelf doSomething]; }];
以下内容是从文档复制的:
一个块形成了它捕获的variables的强有力的参考。 如果你在一个块中使用
self
,那么这个块就形成了一个强烈的self
引用,所以如果self
也有一个强烈的块引用(它通常会这样做),就会产生一个强大的引用循环。 为了避免这个循环,你需要在块的外部创build一个弱的(或__block
)引用,就像上面的例子。
我不明白“弱(或__block
)”是什么意思?
是
__block typeof(self) tmpSelf = self;
和
__weak typeof(self) tmpSelf = self;
这里完全一样吗?
我在文件中发现了另一篇文章:
注意:在垃圾回收环境中,如果将
__weak
和__block
修饰符同时应用于某个variables,则该块将不会确保它保持活动状态。
所以,我完全不解。
从关于__block的文档
__blockvariables存在于variables的词法范围和在variables的词法范围内声明或创build的所有块和块副本之间共享的存储中。 因此,如果帧中声明的块的任何副本超过帧的末尾(例如,通过被排队到某个地方供以后执行),那么存储将在存储栈帧的情况下幸免于难。 给定词法范围中的多个块可以同时使用共享variables。
从关于__weak的文档
__weak指定一个不保持被引用对象活动的引用。 当没有强引用时,弱引用设置为零。
所以他们在技术上是不同的东西。 __block将停止从您的外部作用域复制到您的块范围的variables。 __weak是一个自我划定的弱指针。
注意我在技术上说,因为你的情况他们会做(几乎)相同的事情。 唯一的区别是如果您使用ARC或不。 如果您的项目使用ARC并且仅适用于iOS4.3及更高版本,请使用__weak。 如果全局范围引用是以某种方式发布的,它确保引用设置为nil。 如果您的项目不使用ARC或者用于较旧的操作系统版本,请使用__block。
这里有一个微妙的区别,确保你明白这一点。
编辑:另一个难题是__unsafe_unretained。 这个修饰符与__weak几乎相同,但是在4.3之前的运行时环境中。 然而,它不会设置为零,并可以给你挂指针。
在手动引用计数模式下,__block id x; 具有不保留x的效果。 在ARC模式下,__block id x; 默认保留x(就像所有其他值一样)。 要获得ARC下的手动引用计数模式行为,可以使用__unsafe_unretained __block id x ;. 因为名字__unsafe_unretained意味着,但是,有一个非保留的variables是危险的(因为它可以吊),因此不鼓励。 两个更好的select是使用__weak(如果您不需要支持iOS 4或OS X v10.6),或者将__block值设置为零来中断保留周期。
苹果文档