您仍需要了解的与内存相关的主要问题是保留周期。当一个对象具有指向另一对象的强指针而目标对象具有指向原始对象的强指针时,会发生这种情况。即使删除了对这些对象的所有其他引用,它们仍然会相互保留并且不会被释放。这也可能是间接发生的,可能是链中的最后一个对象引用了较早的对象。
正是由于这个原因,存在__unsafe_unretained
和__weak
所有权限定词。前者将不会保留其指向的任何对象,但会留出该对象消失并指向内存不足的可能性,而后者不会保留该对象,并在释放目标时自动将其自身设置为nil。在这两者之间,__weak
在支持它的平台上通常是首选。
您可以将这些限定符用于诸如委托之类的事情,在这种情况下,您不希望对象保留其委托并可能导致周期。
与内存相关的另外两个重要问题是对Core Foundation对象的处理以及malloc()
为这类分配的内存char*
。ARC不管理这些类型,仅管理Objective-C对象,因此您仍然需要自己处理它们。核心基础类型可能特别棘手,因为有时需要将它们跨接至匹配的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问题。