2013-06-29 76 views
6

我正在阅读关于__block variables的文档,并考虑了使用__block的情况。对我来说,这似乎是我需要它在两种情况下:为什么__block变量不被保留(在非ARC环境中)?

  • 为了纪念一个变量作为读写块
  • 内使用时,为了避免块内引用自当保留周期

从表面上看,这两件事似乎并不相关。我认为,__block变量不被保留为我需要记住的避免保留周期的特定用例的更多技巧。

我想知道,是否有一个更重要的建筑原因,为什么他们不能被保留?我认为其他关键字可能会更清楚地表明这一点,以免混淆上面列出的两个功能。

更新 -

我应该提到这是不使用ARC的代码。我现在看到__block变量实际上保留在ARC中。

+2

您只使用'__block'作为第一个。您可以使用'__weak'而不是'__block'来避免保留周期。 – rmaddy

+2

另外,你在哪里得到__block变量不被保留的想法? ARC会自动保留它们,就像常规变量一样。 –

+2

在ARC之前,__block变量确实不被保留为避免保留周期的机制。这一点随着ARC而改变,并记录在转换到ARC版本说明中。 –

回答

12

__block如果使用手动引用计数,则不会保留变量。究其原因可以在这里找到:http://www.mikeash.com/pyblog/friday-qa-2009-08-14-practical-blocks.html

一个简单的解决方法,这在于一个事实,即__block变量 不会被保留。这是因为这样的变量是可变的,而且它们的自动内存管理会要求每个变种都在后台生成内存管理代码。这被认为是太侵入性并且难以正确地进行,特别是因为同一块 块可能同时从多个线程执行。

,并在这里:http://lists.apple.com/archives/objc-language/2009/Dec/msg00100.html

有没有办法在变量中的值的重新分配,以适当和有效管理保留计数 。

(我找不到苹果文档中的“官方”参考)

正如"Transitioning to ARC Release Notes"记载,这种行为与ARC改变:

在手动引用计数模式, __block id x;的影响不是 保留x。在ARC模式下,__block id x;默认为保留x(只有 与所有其他值一样)。要获得ARC下的手动引用计数模式 行为,可以使用__unsafe_unretained __block id x;。 因为名称__unsafe_unretained意味着,但是,有一个 非保留变量是危险的(因为它可能会晃),因此不鼓励 。两个更好的选择是使用__weak(如果 您不需要支持iOS 4或OS X v10.6),或者将__block 的值设置为nil以打破保留周期。

+0

不错,这是有道理的。谢谢。 –

+0

@darren:在再次阅读这些引用之后,似乎我认为避免保留循环比__block变量的设计目标更具副作用。 –