您仍需要注意的主要内存相关问题是保留周期。这发生在一个对象具有强指向另一个的指针时,但目标对象具有强指向原始的指针。即使对这些对象的所有其他引用都被删除,它们仍然会保持对方,并且不会被释放。这也可以通过链中最后一个引用回早期对象的对象链间接发生。
正是因为这个原因,__unsafe_unretained
和__weak
所有权限定符存在。前者不会保留它指向的任何对象,但会留下该对象消失的可能性,并指向不良内存,而后者不保留该对象,并在释放目标时自动将其自身设置为零。其中,__weak
通常在支持它的平台上首选。
您可以使用这些限定符来处理委托等事情,您不希望对象保留其委托并可能导致循环。
另一个与内存有关的重要问题是处理核心基础对象和使用malloc()
分配的内存类型,如char*
。 ARC不管理这些类型,只有Objective-C对象,所以你仍然需要自己处理它们。核心基础类型可能特别棘手,因为它们有时需要桥接到匹配的Objective-C对象,反之亦然。这意味着当CF类型和Objective-C之间桥接时,控制需要从ARC中来回传输。一些与此桥接相关的关键字已被添加,并且Mike Ash对his lengthy ARC writeup中的各种桥接案例进行了很好的描述。
除此之外,还有其他几个不太常见但仍有潜在问题的情况,其中published specification会详细介绍。
许多新行为,基于保持对象的位置,只要有强指针指向它们,就非常类似于Mac上的垃圾收集。但是,技术基础非常不同。这种内存管理方式不是定期运行垃圾收集器进程来清理不再指向的对象,而是依赖于我们在Objective-C中需要遵守的严格的保留/释放规则。
ARC只需要我们多年来必须做的重复性内存管理任务,并将它们卸载到编译器中,因此我们再也不用担心它们了。这样,您就不会在垃圾收集平台上遇到暂停问题或锯齿形内存配置文件。我在垃圾收集的Mac应用程序中遇到过这两个问题,并且很想看看他们在ARC下的行为。
有关垃圾收集与ARC相关的更多信息,请参阅this very interesting response by Chris Lattner on the Objective-C mailing list,其中列出了ARC在Objective-C 2.0垃圾收集方面的许多优势。我遇到了他描述的几个GC问题。
感谢您的详细回答。我遇到了同样的问题,我在_unsafe_unretained下定义了一个委托,并让我的应用程序崩溃,后来通过更改为强壮的方式修复了它,但现在它有内存泄漏。所以,我改变了它的弱点,像魅力一样运作。 – chathuram 2013-01-22 19:59:44
@ichathura哇!你将我从ARC泥沼中拯救出来。我在使用CMPopTipView时遇到过相同的崩溃。 – Nianliang 2013-06-28 15:46:13
@BradLarson:“你没有在垃圾收集平台上遇到的暂停问题或锯齿内存配置文件”。我期望从基于范围的回收中获得更差的停止和锯齿内存配置文件,以及引用计数的性能更差,所以我希望看到一个真正的比较。 – 2016-04-16 13:08:16