使用objective-c块时避免泄漏的最佳实践是啥?
Posted
技术标签:
【中文标题】使用objective-c块时避免泄漏的最佳实践是啥?【英文标题】:What are the best practices to avoid leaks when using objective-c blocks?使用objective-c块时避免泄漏的最佳实践是什么? 【发布时间】:2013-05-07 17:59:13 【问题描述】:我已经使用块有一段时间了,我试图了解所有可能的泄漏情况。我已经阅读了很多关于“保留循环循环”的内容,但我认为也许还有其他可能的情况。另外,我在考虑一些简单的情况,比如:如果你在一个块中调用一个块怎么办?如果我们使用 ARC,块内存管理是否不同?如何使用仪器(或其他工具)查找块是否泄漏内存?
【问题讨论】:
抓拍自己的时候特别要担心:developer.apple.com/library/ios/#documentation/cocoa/conceptual/… 【参考方案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
限定符。
块保留它们引用的对象(除非对象是合格的,例如 MRC 中的 __block
或 ARC 中的 __weak
)。使用块这一事实与代码是否泄漏无关。这取决于您选择的 ARC v MRC 以及您是否避免了保留周期,如果使用 MRC,您是否包含了必要的 release
语句。
在查找泄漏方面,标准工具都可以正常工作:
尤其是在做非 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];
这样,当对象被释放时,您会在控制台上看到一条消息。
如果您担心泄漏,使用 ARC 是 (恕我直言) 消除许多普通泄漏的最简单方法之一。通过简单的省略release
或autorelease
在非ARC 代码中泄漏是非常容易的(不过,不可否认,以上链接将帮助您找到它们)。由于一个简单的“哦,我忘了release
”,在ARC中泄漏要困难得多。
参考文献
Blocks Programming Topics
Working with BlocksObjective-C 编程指南部分
Advanced Memory Management Guide
Transitioning to ARC Release Notes
【讨论】:
"在 ARC 和非 ARC 中没有明显不同" 一方面,__block
变量的内存管理在 MRC 和 ARC 之间有所不同
@LuisEspinoza:在 ARC 中,对象指针类型的 __block
变量会自动被块保留。但是,在 MRC 中,__block
对象指针类型的变量不会自动保留。
@newacct 同意。这不是我试图传达的重点,但我可以看到它很容易以这种方式阅读,并且我试图澄清。以上是关于使用objective-c块时避免泄漏的最佳实践是啥?的主要内容,如果未能解决你的问题,请参考以下文章
在objective-c或swift中覆盖pod文件方法的最佳实践是啥?