【问题标题】:What are the best practices to avoid leaks when using objective-c blocks?使用objective-c块时避免泄漏的最佳实践是什么?
【发布时间】:2013-05-07 17:59:13
【问题描述】:

我已经使用块有一段时间了,我试图了解所有可能的泄漏情况。我已经阅读了很多关于“保留循环循环”的内容,但我认为也许还有其他可能的情况。另外,我在考虑一些简单的情况,比如:如果你在一个块中调用一个块怎么办?如果我们使用 ARC,块内存管理是否不同?如何使用仪器(或其他工具)查找块是否泄漏内存?

【问题讨论】:

标签: ios objective-c memory-management memory-leaks objective-c-blocks


【解决方案1】:

简短回答:块本身不会引入任何特殊的泄漏问题(除了特殊情况下的保留周期,如下所述)。

长答案:几个想法:

  1. 除了如果您未能Avoid Strong Reference Cycles when Capturing self 导致的保留周期(在 ARC 中也称为强引用周期),确实没有其他与块相关的特殊泄漏风险。如果您记得块对其引用的对象保持强引用,那么只需遵循标准basic rules of memory management。

    如 Use Lifetime Qualifiers to Avoid Strong Reference Cycles 中所述,在 MRC 中,您可以使用 __block 限定符来解决这些强引用循环,但在 ARC 中,您可以使用 __weak 限定符。

  2. 1234563 .
  3. 块保留它们引用的对象(除非对象是合格的,例如 MRC 中的 __block 或 ARC 中的 __weak)。使用块这一事实与代码是否泄漏无关。这取决于您选择的 ARC v MRC 以及您是否避免了保留周期,如果使用 MRC,您是否包含了必要的 release 语句。

  4. 在查找泄漏方面,标准工具都可以正常工作:

    • 尤其是在做非 ARC 代码时,静态分析器(shift+command+B 或从“产品”菜单)非常有用。

    • Instruments 用户指南中的Finding Leaks in Your App 讨论。

    • 有时对于强参考周期,仪器中的泄漏工具并不总是对其进行标记。此时,有时使用 Instruments 中的分配工具很有用,突出显示您怀疑应该已释放但未释放的一些分配,它会显示分配该内存的内容。见iOS app with ARC, find who is owner of an object

    • 如果您想知道某个对象是否被正确释放,向应该释放的对象添加诊断性dealloc 实现很有用:

      - (void)dealloc
      {
          NSLog(@"%s", __FUNCTION__);
      
          // if non-ARC, remember to include the following line, too:
          //
          // [super dealloc];
      }
      

      这样,当对象被释放时,您会在控制台上看到一条消息。

  5. 如果您担心泄漏,使用 ARC 是 (恕我直言) 消除许多普通泄漏的最简单方法之一。通过简单的省略release 或autorelease 在非ARC 代码中泄漏是非常容易的(不过,不可否认,以上链接将帮助您找到它们)。由于一个简单的“哦,我忘了release”,在ARC中泄漏要困难得多。

参考文献

【讨论】:

  • "在 ARC 和非 ARC 中没有明显不同" 一方面,__block 变量的内存管理在 MRC 和 ARC 之间有所不同
  • @LuisEspinoza:在 ARC 中,对象指针类型的 __block 变量会自动被块保留。但是,在 MRC 中,__block 对象指针类型的变量不会自动保留。
  • @newacct 同意。这不是我试图传达的重点,但我可以看到它很容易以这种方式阅读,并且我试图澄清。
猜你喜欢
  • 2022-10-01
  • 2014-07-04
  • 1970-01-01
  • 2015-05-04
  • 2016-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多