在Mac和iOS平台上,内存泄漏通常是由未释放的指针引起的。传统上,检查您的分配、副本和保留以确保每个都有相应的发布消息一直是极其重要的。
The toolchain that comes with Xcode 4.2 introduces automatic reference counting (ARC) with the latest version of the LLVM compiler, that totally does away with this problem by getting the compiler to memory-manage your stuff for you. That's pretty cool, and it does cut lots of unnecessary, mundane development time and prevent a lot of careless memory leaks that are easy to fix with proper retain/release balance. Even autorelease pools need to be managed differently when you enable ARC for your Mac and iOS apps (as you shouldn't allocate your own NSAutoreleasePools anymore).
但是,还有哪些内存泄漏是我仍然需要注意的呢?
另外,Mac OS X和iOS上的ARC和Mac OS X上的垃圾收集有什么不同?
您仍然需要注意的与内存相关的主要问题是保留周期。当一个对象有指向另一个对象的强指针,而目标对象有指向原始对象的强指针时,就会发生这种情况。即使删除了对这些对象的所有其他引用,它们仍然会彼此保留,不会被释放。这也可以间接发生,通过一个对象链,链中的最后一个对象可能引用回一个较早的对象。
正是由于这个原因,才存在__unsafe_unretained和__weak所有权限定符。前者不会保留它所指向的任何对象,但保留了该对象消失并指向坏内存的可能性,而后者不保留对象,并在其目标被释放时自动将自己设置为nil。在这两者中,__weak通常是支持它的平台的首选。
您可以将这些限定符用于委托之类的事情,其中您不希望对象保留其委托并可能导致循环。
Another couple of significant memory-related concerns are the handling of Core Foundation objects and memory allocated using malloc() for types like char*. ARC does not manage these types, only Objective-C objects, so you'll still need to deal with them yourself. Core Foundation types can be particularly tricky, because sometimes they need to be bridged across to matching Objective-C objects, and vice versa. This means that control needs to be transferred back and forth from ARC when bridging between CF types and Objective-C. Some keywords related to this bridging have been added, and Mike Ash has a great description of various bridging cases in his lengthy ARC writeup.
除此之外,还有其他一些不太常见但仍有潜在问题的情况,已发布的规范详细介绍了这些情况。
很多新的行为都是基于只要有强指针指向对象,就会保留对象,这与Mac上的垃圾收集非常相似。然而,技术基础非常不同。这种风格的内存管理依赖于我们在Objective-C中都需要遵守的严格的保留/释放规则,而不是有一个定期运行的垃圾收集器进程来清理不再被指向的对象。
ARC只是把我们多年来不得不做的重复内存管理任务卸载给编译器,这样我们就再也不用担心它们了。这样,您就不会遇到在垃圾收集平台上遇到的停止问题或锯齿状内存配置文件。我在我的垃圾收集Mac应用程序中经历过这两种情况,我渴望看到它们在ARC下的表现。
关于垃圾收集与ARC的更多信息,请参阅Chris Lattner在Objective-C邮件列表上的这篇非常有趣的回复,在那里他列出了ARC相对于Objective-C 2.0垃圾收集的许多优点。我遇到过他描述的几个GC问题。