您仍然需要注意的与内存相关的主要问题是保留周期。当一个对象具有指向另一个对象的强指针,但目标对象具有指向原始对象的强指针时,就会发生这种情况。即使删除了对这些对象的所有其他引用,它们仍然会相互保持并且不会被释放。这也可以通过一系列对象间接发生,这些对象链中的最后一个对象可能指向较早的对象。
正是出于这个原因,存在__unsafe_unretained
和__weak
所有权限定符。前者不会保留它指向的任何对象,但会保留该对象消失并指向坏内存的可能性,而后者不保留该对象并在其目标被释放时自动将其自身设置为 nil。在这两者中,__weak
通常在支持它的平台上是首选。
您可以将这些限定符用于委托等事物,您不希望对象保留其委托并可能导致循环。
另一个与内存相关的重要问题是处理 Core Foundation 对象和malloc()
为char*
. ARC 不管理这些类型,只管理 Objective-C 对象,因此您仍然需要自己处理它们。Core Foundation 类型可能特别棘手,因为有时它们需要桥接以匹配 Objective-C 对象,反之亦然。这意味着在 CF 类型和 Objective-C 之间进行桥接时,需要从 ARC 来回传输控制。添加了一些与此桥接相关的关键字,Mike Ash 在他冗长的 ARC 文章中对各种桥接案例进行了很好的描述。
除此之外,还有其他一些不太常见但仍有潜在问题的案例,已发布的规范对此进行了详细介绍。
许多新行为基于只要有指向它们的强指针就保留对象,这与 Mac 上的垃圾收集非常相似。但是,技术基础却大相径庭。这种内存管理方式不是让垃圾收集器进程定期运行以清理不再指向的对象,而是依赖于我们都需要在 Objective-C 中遵守的严格的保留/释放规则。
ARC 只需将我们多年来不得不做的重复性内存管理任务卸载到编译器,这样我们就不必再担心它们了。这样,您就不会遇到在垃圾收集平台上遇到的停止问题或锯齿状内存配置文件。我在垃圾收集的 Mac 应用程序中经历了这两种情况,并渴望了解它们在 ARC 下的表现。
有关垃圾收集与 ARC 的更多信息,请参阅Chris Lattner 在 Objective-C 邮件列表中的这个非常有趣的回复,他在其中列出了 ARC 相对于 Objective-C 2.0 垃圾收集的许多优点。我遇到了他描述的几个 GC 问题。