自动引用计数(ARC)在Objective-C中不能预防或最小化哪些类型的内存泄漏?
自动引用计数(ARC)在Objective-C中不能预防或最小化哪些类型的内存泄漏?
在Mac和iOS平台上,内存泄漏通常是由未释放指针引起的。传统上,检查您的allocs,copies和retains是否有相应的释放消息非常重要。
随附Xcode 4.2的工具链引入了自动引用计数(ARC)与最新版本的LLVM编译器,它通过让编译器为您管理内存完全解决了这个问题。这非常酷,可以节省大量不必要、单调的开发时间,并防止许多容易用适当的保留/释放平衡修复的疏忽内存泄漏。即使是autorelease池,在启用Mac和iOS应用程序的ARC时也需要以不同的方式进行管理(因为您不应再分配自己的NSAutoreleasePool
了)。
但是,除了这个,还有哪些内存泄漏是它无法预防的,我仍然需要注意的呢?
作为奖励,Mac OS X和iOS上的ARC以及Mac OS X上的垃圾回收之间有什么区别?
你仍然需要注意的主要与内存相关的问题是保留环。这种情况发生在一个对象对另一个对象有强指针引用,但目标对象又有一个强指针指回原始对象。即使删除了对这些对象的所有其他引用,它们仍然会相互保留,并且不会被释放。这也可能间接发生,由一系列对象组成的链条,可能最后一个对象会引用回早期的对象。
正是因为这个原因,__unsafe_unretained
和__weak
所有权限定符存在。前者不会保留其指向的任何对象,但会留下该对象消失的可能性,并且指向坏内存,而后者不会保留对象,并且在其目标被释放时自动设置为nil。在这两种情况中,__weak
通常是支持它的平台上首选的。
你可以在诸如委托(delegate)等情况下使用这些限定符,其中你不希望对象保留其委托并潜在地导致循环。
另外还有一些重要的与内存相关的问题是如何处理Core Foundation对象以及使用malloc()
分配的用于char*
等类型的内存。ARC不管理这些类型,仅管理Objective-C对象,因此您仍然需要自己处理它们。Core Foundation类型可能会特别棘手,因为有时它们需要桥接到匹配的Objective-C对象,反之亦然。这意味着在CF类型和Objective-C之间进行桥接时需要在ARC和控制之间来回转移。已添加了一些与此桥接相关的关键字,Mike Ash在他的详细ARC写作中描述了各种桥接情况。
想了解垃圾回收和自动引用计数(ARC)的更多内容,请参阅Objective-C邮件列表上Chris Lattner的这篇非常有趣的回复,他在回复中列举了ARC相对于Objective-C 2.0垃圾回收的许多优点。我遇到了他描述的一些垃圾回收问题。