6

我正在阅读有关__block variables的文档,并考虑使用 __block 的情况。对我来说,似乎我在两种情况下需要它:

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

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

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

更新 -

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

4

1 回答 1

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

在重新分配变量内的值时,无法正确有效地管理保留计数。

(我在 Apple 文档中找不到“官方”参考资料。)

正如“过渡到 ARC 发行说明”中所述,这种行为随着 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为中断保留周期。

于 2013-06-29T21:38:34.580 回答