__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值设置为零来中断保留周期。

苹果文档