【发布时间】:2012-12-21 22:03:06
【问题描述】:
这是为了澄清我对 ARC 概念理解的一些疑问。如果 ARC 是一种编译时技术,为什么它不能在所有版本的 iOS 和 OS X 上使用?
【问题讨论】:
标签: objective-c ios macos memory-management automatic-ref-counting
这是为了澄清我对 ARC 概念理解的一些疑问。如果 ARC 是一种编译时技术,为什么它不能在所有版本的 iOS 和 OS X 上使用?
【问题讨论】:
标签: objective-c ios macos memory-management automatic-ref-counting
ARC 不仅仅是一种编译时技术。它还依赖于一些运行时组件。这有两个部分:
引用计数。在编译时,ARC 引入了对一堆辅助函数的调用。这些都是documented online,但重要的是objc_retain()、objc_release()和objc_autorelease()。它们与在对象上调用 -retain、-release 或 -autorelease 执行相同的操作,但是在 ARC 下可以使用运行时函数完成一些额外的优化(特别是,当一个方法返回一个自动释放的对象和调用者将值存储到一个强变量中,自动释放+保留可能可以完全跳过)。这些运行时函数是增加操作系统要求的原因。幸运的是,如果您针对较旧的操作系统,Xcode 可以链接到一个名为 libarclite 的静态库,该库提供这些功能的实现,从而允许您在针对较旧的操作系统(例如 iOS 4.3)时使用 ARC。缺点是这些函数没有“真正” ARC 所做的优化,因此性能可能会受到轻微影响。
归零弱参考支持。这还需要一组运行时函数,加上运行时内存管理工作方式的一些内部更改,以及框架中的一些更改以更好地支持归零弱引用。具体而言,内存管理更改是为什么不能像其他 ARC 一样使用 libarclite 向后移植归零弱引用支持。
【讨论】:
ARC 需要一些运行时函数。这些函数在clang ARC documentation中。
iOS 5.0 和 Mac OS X 10.7(及更高版本)包含这些功能。
为了让您能够将应用程序部署到较旧的操作系统版本,Apple 包含一个名为“arclite”的静态库,它定义了其中的大部分功能。如果您的部署目标是较旧的操作系统,Xcode 会将您的应用与 arclite 链接。
所以你可能会问,为什么 arclite 不能在所有旧版本的 iOS 和 OS X 上运行?我不确定(也许苹果以外的人都不知道)。一个合理的猜测是 arclite 需要挂钩到 Objective-C 运行时。运行时可以在操作系统版本之间更改。 Apple 不想尝试支持他们曾经发布的每个版本的运行时,所以他们选择了合理的截止值,并让 arclite 支持这些截止值之后的每个版本。这简化了 arclite 的实现并减少了测试负担。
请注意,arclite 不支持将弱引用归零。也许这是一个在旧版本的运行时上难以支持的功能,即使是那些在截止之后的版本。
【讨论】:
libarclite预计可以在所有早期版本的 iOS 和 OS X 上工作,只是没有得到官方支持。至于弱支持,则需要对内存管理的内部进行更改,而使用静态库根本无法提供。