我使用 block 已经有一段时间了,我试图了解所有可能发生泄漏的情况。我已经阅读了很多关于“保留循环循环”的内容,但我认为也许还有其他可能的情况。另外,我在考虑一些简单的情况,比如:如果你在一个 block 中调用一个 block 怎么办?如果我们使用或不使用 ARC, block 内存管理是否不同?如何使用仪器(或其他一些工具)查找 block 是否正在泄漏内存?
最佳答案
简短回答: block 本身不会引入任何特殊的泄漏问题(特殊情况下的保留循环除外,如下所述)。
长答案:几个想法:
除了保留循环(在 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
限定符。如果您将 block 放在 block 中,那不会引入任何额外的泄漏风险(除非您编造一些循环引用集导致强引用循环,这在嵌套block中通常不太可能发生) .
block 保留它们引用的对象(除非对象是限定的,例如 MRC 中的
__block
或 ARC 中的__weak
)。使用 block 这一事实与代码是否泄漏无关。这取决于您选择的 ARC v MRC,以及您是否避免了保留循环,如果使用 MRC,您是否包含了必要的release
语句。在查找漏洞方面,标准工具都可以正常工作:
特别是在执行非 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]; }
这样,当对象被释放时,您会在控制台上看到一条消息。
如果您担心泄漏,使用 ARC(恕我直言)是消除许多普通泄漏的最简单方法之一。在非 ARC 代码中通过简单省略
release
或autorelease
非常容易泄漏(不过,无可否认,上面的链接可以帮助您找到它们)。由于简单的“哦,我忘了release
。” ,在 ARC 中泄漏要困难得多
引用资料
Working with Blocks Programming with Objective-C 指南部分
关于ios - 使用 Objective-C block 时避免泄漏的最佳做法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16526499/