我一直在使用块一段时间,我试图了解所有泄漏的可能情况。我已经阅读了很多关于“保留循环循环”的内容,但我认为可能还有其他可能的情况。另外,我正在考虑一些简单的情况,例如:如果你在一个块内调用一个块怎么办?如果我们使用ARC,块存储器管理是否不同?如何找到一个块是否用仪器(或其他工具)泄漏内存?
答案 0 :(得分:24)
简短回答:块本身并不会引入任何特殊的泄漏问题(除了特殊情况下的保留周期,如下所述)。
答案很长:有几点想法:
除了保留周期(在ARC中也称为强引用周期)之外,如果您未能Avoid Strong Reference Cycles when Capturing self),则确实没有与块相关的其他特殊泄漏风险。如果您记得块保持对它们引用的对象的强引用,那么只需遵循标准basic rules of memory management。
如Use Lifetime Qualifiers to Avoid Strong Reference Cycles中所述,在MRC中,您可以使用__block
限定符来解决这些强引用周期,但在ARC中,您可以使用__weak
限定符。
如果您将块放入块中,那么不会引入任何额外的泄漏风险(除非您编写一些引用强引用周期的循环引用集,这通常在块内执行块时不太可能)
块保留它们引用的对象(除非对象是合格的,例如MRC中的__block
或ARC中的__weak
)。使用块的事实与代码是否泄漏无关。这是您选择ARC v MRC的功能,以及您是否避免了保留周期,如果进行了MRC,您是否已包含必要的release
语句。
在查找泄漏方面,标准工具都可以正常工作:
特别是在进行非ARC代码时,静态分析器( shift + 命令 + B 或从中选择“分析” “产品”菜单非常有用。
用户指南中的Finding Leaks in Your App讨论。
有时,对于强参考周期,仪器中的Leaks工具不会始终标记它。此时,使用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是(恕我直言)消除许多普通泄漏的最简单方法之一。使用简单的省略release
或autorelease
非常容易在非ARC代码中泄漏(尽管如此,上述链接可以帮助您找到它们)。因为一个简单的“哦,我忘了release
,在ARC中泄漏要困难得多。”