17.5 垃圾回收

本书到目前为止,你已经创建了在可管理的内存运行时环境中运行的程序。上一节中总结的内存管理规则适用于这种环境,在这种环境中需要处理自动释放池,与保持和释放对象的相关问题,以及对象所有权。

从Objective C 2.0开始,提供了一种替代的内存管理形式,称为垃圾回收。有了垃圾回收,就不必考虑有关保持和释放对象、自动释放池或保持计数的问题了。系统可自动跟踪拥有其他哪些对象的那些对象,并且在程序执行期间需要内存空间时,自动释放(即垃圾回收)不再被引用的对象。

如果事情如此简单,为什么我们不在本书的例子中都使用垃圾回收,去掉所有关于内存管理的内容呢?其中有3个原因:首先,即使环境支持垃圾回收,最好也要知道是谁拥有对象,并跟踪你何时不再需要它们了。这样在编写代码时就会更加小心,因为你了解程序中对象之间的关系以及它们的生命周期。

第二个原因前面说过,就是iPhone运行时环境不支持垃圾回收,所以为该平台开发程序时不能使用这个功能。

第三个原因适用于要编写库例程、插件或共享代码的人。因为这些代码可能会被加载到已经垃圾回收或未被垃圾回收的进程中,所以必须要编写在这两种环境中使用的代码。这就意味着,你需要使用本书中介绍的内存管理技巧编写代码,还意味着必须在禁用和启用垃圾回收的情况下测试代码。

如果决定要使用垃圾回收,那么使用Xcode生成程序时必须开启该功能。可通过Project, Edit Project Settings菜单完成该任务。在“GCC 4.0—Code Generation”设置下,会看到一个称为Objective-C Garbage Collection的设置。将该设置从默认值Unsupported改为Required,指定在程序生成时启用自动垃圾回收功能(参见图17-1)。

17.5 垃圾回收 - 图1

图 17-1 启用垃圾回收功能

启用垃圾回收功能后,程序仍可进行retain、autorelease、release和dealloc方法调用。然而这些调用会被忽略。这样,可以开发同时能在内存管理和垃圾回收环境中运行的程序。然而这也意味着,如果需要代码能在这两种环境中运行,那么就不能完成dealloc方法中实现的所有功能。原因前面已经说过,启用垃圾回收后会忽略dealloc调用。

注意本章介绍的内存管理技术对于大多数应用程序足够了。然而在更为复杂的情况中,如编写多线程应用程序时,可能还需要更多的技术。要想了解有关这些问题以及与垃圾回收有关的其他信息,请参见附录D“资源”。