ios - 使用 Objective-C block 时避免泄漏的最佳做法是什么?

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

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

最佳答案

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

长答案:几个想法:

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

    正如在 Use Lifetime Qualifiers to Avoid Strong Reference Cycles 中讨论的那样,在 MRC 中你可以使用 __block 限定符来解决这些强引用循环,但是在 ARC 中,你可以使用 __weak 限定符。

  2. 如果您将 block 放在 block 中,那不会引入任何额外的泄漏风险(除非您编造一些循环引用集导致强引用循环,这在嵌套block中通常不太可能发生) .

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

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

    • 特别是在执行非 ARC 代码时,静态分析器(shift+command+B 或从中选择“分析” “产品”菜单)非常有用。

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

    • 有时对于强引用循环,它不会总是被仪器中的泄漏工具标记。在这一点上,有时使用 Instruments 中的 Allocations 工具很有用,突出显示您怀疑应该释放但没有释放的一些分配,它会显示分配该内存的内容。参见 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(恕我直言)是消除许多普通泄漏的最简单方法之一。在非 ARC 代码中通过简单省略 releaseautorelease 非常容易泄漏(不过,无可否认,上面的链接可以帮助您找到它们)。由于简单的“哦,我忘了release。”

  6. ,在 ARC 中泄漏要困难得多

引用资料

关于ios - 使用 Objective-C block 时避免泄漏的最佳做法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16526499/

相关文章:

ios - NSURLSession 失效并取消 : Bad Access

Java:将内存刷新到磁盘

ios - 绘制一条 SKShapeNode 线 color-gradient 从一种颜色到另一种颜色

ios - 在 iphone 6 上具有 600x600 pt 框架的 UIViews 加上尺寸等级

java - 我是否正确地实习了我的字符串?

ios - 使用 RATreeView 的 tableView endUpdates 崩溃

ios - Xcode 8 没有警告将 NSString 分配给 NSInteger?

ios - NSTimer 不会在 React Native 组件中触发

ios - 'UN' 在 UNNotification 中代表什么?

ios - 在 Xcode 5 中将 iPhone NIB 转换为 iPad NIB