Objective-C自动引用计数和垃圾收集有什么区别?
在Xcode 4.2中引入新的自动引用计数(ARC)后,我们不再需要在Objective-C中手动pipe理保留/释放。
这看起来很像垃圾收集,就像Mac上的Objective-C和其他语言一样。 ARC与垃圾收集有何不同?
简短而又甜蜜的回答如下:
java的GC是运行时,而ARC是编译时。
GC在运行时引用对象并检查对象运行时的依赖关系。 ARC在编译时附加释放,保留,自动释放调用。
正如我在这里的回答中所描述的,ARC可以提供手动内存pipe理和跟踪垃圾回收的最佳function。 它大部分消除了开发人员跟踪Objective-C对象上的手动保留,发布和自动释放的需要,但却避免了需要一个垃圾回收器进程,这个进程可以在移动设备上使用有限的资源,并在正在运行的应用程序中偶尔造成连接。
ARC通过应用所有Objective-C开发者多年来必须使用的规则,在编译时插入引用计数所需的适当的保留和释放。 这使开发人员不必自己pipe理它。 由于保留和释放是在编译时插入的,因此不需要收集器进程来持续扫描内存并删除未引用的对象。
跟踪垃圾收集已经超过了ARC的一个小优点是,ARC 不会为你处理保留周期 ,跟踪垃圾收集可以挑选这些周期 。
关于这个问题的一个很好的阅读来自苹果公司Objective-C邮件列表上的这个主题 ,Chris Lattner曾这样说过:
GC优于ARC的主要优点是收集保留周期。 第二个优点是“保留”的作业是“primefaces的”,因为它们是一个简单的商店。 ARC比libauto GC有几大优势:
- 它具有确定性的对象回收(当对象的最后一个强引用消失时),GC在某个时间后释放对象。 这就定义了一些可能存在于GC应用程序中的细微错误,这些错误由于收集器不会在“错误窗口”中触发而被公开。
- ARC的高水位通常要比GC低得多,因为物体被释放得更快。
- libauto提供了一个脆弱的编程模型,你必须小心不要丢失写屏障等。
- 并不是所有的系统框架都是GC清理的,框架偶尔会随着它们的发展而倒退。
- ARC不会遭受错误的根源。 libauto保守地扫描堆栈,这意味着看起来像指针的整数可以根目标graphics。
- ARC没有任何事情,并停止你的应用程序,导致UI口吃。 就GC实现而言,libauto是非常先进的,因为它不会立即停止每个线程,但它通常最终会停止所有的UI线程。
我目前正在将手动内存pipe理的项目以及那些使用Objective-C垃圾回收的项目迁移到ARC。 在一段时间的Mac应用程序中使用垃圾回收之后,我发现将这些项目移到ARC中有一些显着的优势。
ARC与垃圾收集有何不同?
ARC是垃圾收集的一种forms。
你可能是指“ARC和跟踪垃圾收集(像JVM和.NET)有什么区别?”。 主要的区别在于ARC比较慢并且泄漏循环。 这就是为什么JVM和.NET都使用跟踪垃圾收集器。 有关更多信息,请阅读如何引用计数和跟踪垃圾回收比较? 。
ARC依靠编译时间“引用”的对象,这使得它在低功耗模式环境(移动设备)中有效。
GC依赖基于运行时的“可达”对象,这使得它在multithreading环境中更有效率。
手术
ARC将代码注入到可执行文件中,根据其引用计数在未使用的对象上“自动”执行。
GC在运行时工作,因为它将检测未使用的对象图(将消除保留周期),并以不确定的时间间隔
自动参考计数的优点
- 实时的,确定性的破坏对象,因为它们变得不被使用。
- 没有后台处理。
垃圾收集的优势
- GC可以清理整个对象图,包括保留周期。
- GC在后台进行,因此,作为常规应用程序stream程的一部分,内存pipe理工作量减less。
自动引用计数的缺点
- ARC不能自动处理保留周期。
垃圾收集的缺点
- 由于GC发生在后台,对象释放的确切时间框架是未确定的。
- 当GC发生时,应用程序中的其他线程可能暂时被搁置。