关于ios:为什么不保留__block变量(在非ARC环境中)?

Why are __block variables not retained (In non-ARC environments)?

我正在阅读关于块变量的文档,并思考使用块的情况。在我看来,我需要它有两种情况:

  • 在块中使用时将变量标记为读写
  • 在块内引用自身时避免保留循环

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

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

更新-

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


如果使用手动参考计数,则不会保留__block变量。原因如下:http://www.mikeash.com/pyblog/friday-qa-2009-08-14-practical-blocks.html:

A simple workaround to this lies in the fact that __block variables
are not retained. This is because such variables are mutable, and
automatic memory management of them would require each mutation to
generate memory management code behind the scenes. This was seen as
too intrusive and difficult to get right, especially since the same
block may be executing from multiple threads simultaneously.

还有:http://lists.apple.com/archives/objc-language/2009/dec/msg0100.html

There is no way to properly and efficiently manage the retain counts
upon re-assignment of the value within the variable.

(我在苹果文档中找不到"官方"参考。)

如"过渡到ARC发行说明"中所述,此行为随ARC而改变:

In manual reference counting mode, __block id x; has the effect of not
retaining x. In ARC mode, __block id x; defaults to retaining x (just
like all other values). To get the manual reference counting mode
behavior under ARC, you could use __unsafe_unretained __block id x;.
As the name __unsafe_unretained implies, however, having a
non-retained variable is dangerous (because it can dangle) and is
therefore discouraged. Two better options are to either use __weak (if
you don’t need to support iOS 4 or OS X v10.6), or set the __block
value to nil to break the retain cycle.