使用ARC的优点和缺点是什么?

sen*_*thu 42 iphone reference-counting ios ios5 automatic-ref-counting

在iOS项目中使用新的自动引用计数(ARC)内存管理方式有哪些优缺点?

使用iOS 5.0 SDK进行开发时,您可以选择不使用ARC吗?

您是否为新项目推荐ARC或手动引用计数(MRC)?

使用ARC的应用程序是否能够在比iOS 5.0更旧的操作系统版本上运行?

jus*_*tin 60

在iOS项目中使用新的自动引用计数(ARC)内存管理方式有哪些优缺点?

ARC程序的执行与编写良好的MRC几乎相同.也就是说,行为差异通常是不可检测的,因为操作顺序和性能都非常接近.

如果您已经知道如何使用手动引用计数(MRC)实现OS X或iOS应用程序,ARC并不真正添加功能 - 它只允许您从源中删除引用计数操作.

如果您不想学习MRC,那么您可能需要先尝试ARC.很多人都在努力或试图忽略MRC的常见做法(例如:我向静态分析器介绍了一些objc开发人员).如果你想避免这些问题,ARC将允许你推迟你的理解; 如果不了解引用计数和对象生命周期和关系,无论是MRC,ARC还是GC,都不能编写非平凡的objc程序.ARC和GC只是从您的源中删除实现,并在大多数情况下做正确的事情.使用ARC和GC,您仍需要提供一些指导.

我没有测量过这个,但值得一提的是,编译 ARC源需要更多的时间和资源.

如果您正在开发的程序使用引用计数相当松散(例如,典型的自动释放量),切换到ARC 可以真正改善程序的执行时间和峰值内存使用量.

使用iOS 5.0 SDK进行开发时,您可以选择不使用ARC吗?

是的,使用CLANG_ENABLE_OBJC_ARC.ARC是二进制兼容的,所有真正发生的事情是编译器会根据当前转换的可见声明自动为您引入适当的引用计数操作(请参阅我的答案,了解为什么转换可见性很重要) .因此,您还可以为项目中的某些源启用和禁用它,并为其他源启用它.

然而,混合模式(一些MRC和一些ARC源)非常复杂,并且巧妙地,特别是可能被编译器复制的实现(例如,内联函数的主体可能是不正确的).这种混合模式问题很难分离.在这方面,ObjC++程序和来源将特别困难.此外,行为可能会根据您的优化设置而有所不同(作为一个示例); 在调试版本中完美运行的程序可能会在发布时引入泄漏或僵尸.

您是否为新项目推荐ARC或手动引用计数(MRC)?

就个人而言,我会坚持MRC一段时间.即使ARC已经在实际使用中进行了测试,但很可能会出现一些问题,这些问题会出现在复杂的场景中,您可能希望避免成为第一个知道和调试的问题.OS X的垃圾收集是您可能想要等待的原因的一个示例.作为一个例子,交换机可以在对象被销毁时改变 - 您的对象可能会被更快地销毁,并且永远不会被放置在自动释放池中.它也可以改变释放ivars的顺序,这可能会产生一些副作用.

我还有一个很大的代码库,我不想在这个时候丢失一周的时间来测试这个功能.最后,向后兼容性对我来说仍然很重要.

使用ARC的应用程序是否能够在比iOS 5.0更旧的操作系统版本上运行?

如果您使用MRC进行开发,它将向后兼容.如果使用ARC开发,则不一定兼容.事实上,如果没有一点额外的工作,它甚至可能无法编译.某些早期版本中提供了运行时的要求. 另见这个问题.如果您需要向后兼容性,ARC将不适用于某些操作系统版本.

最后,如果您要将选择限制在GC或ARC,我建议使用ARC.

  • 真是好评.我们讨论了将我们的大型企业项目从MRC迁移到ARC,但我们认为最好在大型项目或复杂的对象模型上使用MRC,因为我们可以控制它.在大多数情况下,我们甚至不会手动调用保留/释放.我们保留了所有内容的属性,并在分配时自动发布.但是我们偶尔会发现需要直接控制内存的情况. (5认同)

Rol*_*asR 1

你关闭/打开它的CLANG_ENABLE_OBJC_ARC = NO 好处是你必须编写更少的代码并且内存管理更容易。缺点是您必须重新学习有关内存管理的所有知识:)我更喜欢将其关闭。

  • 事情比这更复杂。ARC 既快又慢,具体取决于具体情况。典型的结果是:更多的保留和释放(更慢),更少的自动释放(更快,更少的内存)。了解特定代码更快还是更慢的唯一方法是测量。 (2认同)