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有几大优势:

  1. 它具有确定性的对象回收(当对象的最后一个强引用消失时),GC在某个时间后释放对象。 这就定义了一些可能存在于GC应用程序中的细微错误,这些错误由于收集器不会在“错误窗口”中触发而被公开。
  2. ARC的高水位通常要比GC低得多,因为物体被释放得更快。
  3. libauto提供了一个脆弱的编程模型,你必须小心不要丢失写屏障等。
  4. 并不是所有的系统框架都是GC清理的,框架偶尔会随着它们的发展而倒退。
  5. ARC不会遭受错误的根源。 libauto保守地扫描堆栈,这意味着看起来像指针的整数可以根目标graphics。
  6. 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发生时,应用程序中的其他线程可能暂时被搁置。