ARC,值得使用吗?

18

当我从C++(和一点Java)转移到Objective C(iOS)时,我很难理解iOS中的内存管理。但现在这些都似乎很自然了,我知道保留、自动释放、复制和释放的东西。阅读有关ARC的文章后,我想知道使用ARC是否还有更多好处,或者仅仅是你不用担心内存管理。在转移到ARC之前,我想知道转移是否值得。

  1. XCode有“转换为Objective C ARC”菜单。 转换是否如此简单(没有什么可担心的)?
  2. 它是否有助于减少我的应用程序的内存占用,内存泄漏等(以某种方式)?
  3. 它是否对我的应用程序具有显着的测试影响?
  4. 有哪些非明显的优点?
  5. 转移到它是否有任何缺点?

你是在谈论新应用程序还是现有的应用程序?如果是现有的,您预计将进行多少未来修改(如果有)?代码相对简单,还是可能会做很多奇怪的事情?纯Objective-C还是混合了C/C++数据结构? - Hot Licks
1
可能是重复的问题:iOS:使用ARC还是不使用ARC?优缺点 - Brad Larson
@Brad Larson:这就是为什么我讨厌由多个部分问题组成的问题。 - BoltClock
最近有很多类似的问题...很多人都犹豫不决!(包括我) - Nicolas Miari
我观察到,当一个人使用ARC进行编码时,他们处理手动保留/释放的"蜘蛛感"会非常迅速地丧失。这是一种在不锻炼时迅速萎缩的肌肉。 - Hot Licks
7个回答

23

以下是我对ARC的具体看法:

1)XCode有“转换为Objective C ARC”菜单。转换过程是否简单(无需担心)?

它很简单,很有效。使用它吧。但正如Kevin Low所指出的那样,您需要修改使用Core Foundation对象的部分内容。这仅需要健康的应用__bridge__bridge_transfer即可。

2)它是否有助于减少我的应用程序的内存占用、内存泄漏等问题(以某种方式)?

不是真的。好吧,有点。它将有助于减少你先前编码错误导致的内存泄漏。但它不会减少内存占用。

3)它是否会对我的应用程序产生很大的测试影响?

完全没有。

4)有哪些非显而易见的优势?

未来。编译器了解对象引用计数的复杂知识将提供更多的奖励。例如,ARC已经提供了可爱的objc_retainAutoreleasedReturnValue优化,非常好用。

5)转向它有什么缺点吗?

完全没有。

请相信我的话,开始使用ARC。在我看来,没有理由不这样做,因此优势绝对超过了缺点!

如果您想深入了解ARC的工作原理,以便更好地理解其好处,请查看我的博客文章“深入探究ARC”的系列 - 这里这里这里这里


1
ARC肯定会减少高峰内存占用,因为有些东西会更早地被处理掉——即使应用程序之前正确地处理了内存。 - Steven Fisher
2
不,它不会。如果您认为它会,请提供一个示例来证明。 - mattjgalloway
6
阅读 LLVM 文档中有关此主题的部分 (第 3.2.3 节)。它可以短路自动释放池以处理函数结果,导致内存立即被释放而不是在下一个运行循环中释放。如果您有一个循环包含多个这样的分配,现在您已将高潮使用量降至最低。 - Steven Fisher
1
好的,没问题 :-). 不过我在我的回答中确实谈到了这个优化 - objc_retainAutoreleasedReturnValue。不过,除非你在内部循环中调用返回自动释放对象的方法,否则你不会真正看到太大的差异。而且,那个对象可能因为其他原因仍然会被自动释放,因此没有任何区别。 - mattjgalloway
3
循环与字符串的结合并不罕见。我确信您之前可能已经加上了 @autoreleasepool{},但您必须先意识到这是个问题。无论如何,ARC不会对您的内存使用产生负面影响,而且有可能会帮助您。 - Steven Fisher

18

关于 ARC,你需要知道的是:

编译器比你更了解 Objective-C 和 Cocoa。 我并不是在侮辱你;它比我更了解。可以毫不夸张地说,它的理解程度甚至超过全球大约十几个人。而且它知道如何使用这些规则的技巧,即使我们理解得和它一样好,我们也无法做到。

其余只是细节:

  • 你将写更少的无聊代码。那种枯燥乏味的代码很容易出错。
  • 作为混合编译时和运行时的进程,它可以访问你无法接触到的技巧。
    • 它将比你更好地编写内存管理代码,即使你编写了理论上完美的内存管理代码。
    • 它将减少“高潮”记忆体使用(在没有任何努力的情况下)。
    • 使用零弱引用,避免由悬空指针引起的崩溃就轻松多了。
  • 如果你正在开始一个新应用程序,请停止思考并直接使用它。
  • 如果你有一个现有的应用程序:
    • 你需要重新测试它。你需要确保没有循环引用。
    • 如果你有一个面向 iOS 5 之前版本的现有应用程序,不支持零弱引用。 你应该严肃考虑要求 iOS 5。
    • 如果你有一个面向 iOS 4 之前版本的现有应用程序,根本不能使用。 你在想什么,支持那么老的东西?!
  • 在上一个 Xcode 版本中,它并不完全没有 bug。现在可能还是这样。但它仍然值得使用。

5
  1. 如果你正在使用核心基础框架或非Objective-C代码,那么情况就不像你想象的那么简单,因为你必须手动检查所有Objective-C和核心基础框架之间的类型转换是否被桥接(如果有任何类型转换的话)。对于非Objective-C代码,你仍然需要管理内存。

  2. ARC应该本质上能够帮你处理所有的内存泄漏问题,因为它自动化了保留、释放、复制等操作。到目前为止,我在切换到ARC后从未遇到过Objective-C泄漏的情况。

  3. 不会。构建可能需要花费更长的时间,因为它必须遍历你的所有代码并插入所有的保留和释放代码。

  4. 不确定是否有任何风险。归根结底,所有的ARC都只是自动化工具。

  5. 你还需要了解桥接类型转换,因为你无法为低于iOS 4的设备构建应用程序。

最终,这绝对是值得的。起初我持怀疑态度,但在观看WWDC视频后,我越来越喜欢它的工作方式。


一个小的额外优势是ARC代码可以进行你无法进行的优化。这意味着(与直觉相反)ARC代码应该表现更好。对于第三点,你可能想说,如果这是一个现有的应用程序,在转换后肯定需要重新测试。 - Steven Fisher
OOI,你为什么认为ARC代码表现更好是违反直觉的呢? - mattjgalloway
其实我并不这么认为。但是“它怎么能表现得更好呢?它正在做额外的工作!”这是我听过几次的一个论点。 - Steven Fisher
但它并没有做额外的工作。它很可能会做更少的工作,或者至少会做相同的工作。ARC不是垃圾回收。引用计数仍在进行中。 - mattjgalloway
哦,是的,你是对的。我想测试你的应用程序在大规模转换之后是必要的 =P。 - Kevin Low
我知道,Matt。这些是我经常听到的论点。:) 公平地说,在某些情况下,ARC确实会进行额外的保留/释放操作,主要是因为它理解了一些程序员认为是安全的情况实际上并不安全。但是由于保留/释放速度更快...我猜这些细节人们不需要知道。它更聪明。它更好。它更快。它代码更少。它比世界上大概只有十几个程序员更了解Objective-C和Cocoa。别再想了,直接使用它吧。:) - Steven Fisher

3

你读过ARC文档吗?它回答了你提出的许多问题。

根据我的经验,这是我认为的:

  1. 是的,很简单。但在转换后一定要测试你的应用程序。
  2. 可以帮助减少应用程序的内存使用和泄漏,但不能保证完全达到这个目的。
  3. 是的,你会想在转换为ARC后进行测试。
  4. 你不必再花费大量时间考虑和追踪泄漏。你可以将更多时间和精力放在你应用程序的实际代码上,而不是担心retain/release。即使retain/release代码对你来说是自然和容易的,你也不是没有缺点,偶尔会忘记释放某些东西。ARC不会忘记。
  5. 如果你要支持iOS 4,你需要处理弱引用,因为ARC在iOS 4中不支持它们。

1
我发现:ARC 可以让你的代码运行速度快很多。在苹果的 WWDC 视频中,他们说每个 NSObject 的 retain 和 release 方法都可以节省几个 CPU 周期。这是因为不再需要在运行时检查它了(现在已经外包给编译器了)。每个 retain 大约节省了 6 个 CPU 周期。如果你使用一个创建大量对象的循环,那么你真的可以感受到巨大的差异。
ARC 不仅使代码更快,而且你写的代码更少,从而极大地加快了开发过程。最后但并非最不重要的是,你不必搜索大约 90% 的代码中的内存泄漏。如果你不使用很多低级别的东西,必须使用“__bridge casts”,那么你就完全没有内存泄漏了。
结论:如果你能做到,就去做吧!

1

3) 你应该重新测试你的应用程序,但根据我的经验,它基本上会正常工作。 但是一定要非常仔细地查看所有编译器警告!!!

4) 非明显的优点:当您不必考虑内存管理时,编码速度真的更快。也许这很明显,但它帮助的程度仍然让我感到惊讶。

5) 缺点:实际上唯一的缺点是必须关闭某些第三方库的ARC。

ARC非常有用,我简直无法再编写没有它的代码了。现在没有理由再去处理所有这些问题,而且在实践中它足够好用。


1
观看有关ARC的WWDC视频: https://developer.apple.com/videos/wwdc/2011/?id=323 苹果在该视频中的官方立场是,所有可以使用ARC的应用程序都应该使用ARC。该视频详细介绍了为什么要这样做,并且是该技术的一个很好的概述,因此我不会在此重复介绍。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接