关于iphone:ARC还是ARC?

To ARC or not to ARC? What are the pros and cons?

我还没有使用arc,因为我目前正在研究的项目中的大多数代码都是在iOS 5.0之前编写的。

我只是想知道,不手动保留/释放(以及由此产生的更可靠的代码)是否方便?超过使用ARC的任何"成本"?你对ARC有什么经验,你会推荐它吗?

所以:

  • ARC能给一个项目带来多少好处?
  • 在Java中,ARC是否具有垃圾收集的成本?
  • 你用过弧线吗?如果用过,到目前为止你是怎么找到的?


不会有负面影响。用它。今天就去做。它比您的旧代码快。它比您的旧代码更安全。这比你以前的代码容易。这不是垃圾收集。它没有GC运行时开销。编译器插入将保留并释放您应该拥有的所有位置。但它比你聪明,可以优化那些实际上不需要的(就像它可以展开循环、消除临时变量、内联函数等)。好的。

好吧,现在我来告诉你一些小缺点:好的。

  • 如果你是一个长期的objc开发人员,当你看到arc代码时,你会抽搐大约一周。你会很快克服这个问题的。好的。

  • 在核心基础代码的桥接方面存在一些(非常)小的并发症。在处理任何将id视为void*的事情时,都会稍微复杂一些。像id的C数组这样的事情需要更多的思考才能正确完成。对objc va_args的处理不当也会造成麻烦。在objc指针上涉及数学的大多数事情都比较棘手。在任何情况下,你都不应该有太多这样的东西。好的。

  • 你不能把一个id放在struct中。这是相当罕见的,但有时它被用来打包数据。好的。

  • 如果您没有遵循正确的kvc命名,并且您混合了arc和non-arc代码,那么您将有内存问题。ARC使用KVC命名来决定内存管理。如果都是ARC代码,那就不重要了,因为它在两边都会做同样的"错误"。但是如果它是混合弧/非弧,那么就存在不匹配。好的。

  • 在objc异常抛出期间,arc将泄漏内存。objc异常应该与程序终止的时间非常接近。如果您捕获了大量的objc异常,则说明您使用它们是错误的。使用-fobjc-arc-exceptions可以解决此问题,但会受到以下讨论的处罚:好的。

  • ARC不会在Objc或C++异常抛出中在Objc++代码中泄漏内存,但这是以时间和空间性能为代价的。这是一长串最小化objc++使用的原因中的另一个。好的。

  • ARC在iPhoneOS 3或Mac OS X 10.5或更早版本上根本无法工作。(这使我无法在许多项目中使用ARC。)好的。

  • __weak指针在iOS 4或Mac OS X 10.6上不能正常工作,这很遗憾,但很容易解决。__weak指针很好,但它们不是ARC的第一卖点。好的。

对于95%以上的代码,ARC非常出色,完全没有理由避免它(前提是您可以处理操作系统版本限制)。对于非ARC代码,可以逐个文件传递-fno-objc-arc。不幸的是,Xcode使这一过程比实际中要困难得多。您可能应该将非圆弧代码移动到单独的xcodeproj中以简化这一过程。好的。

总之,尽快切换到ARC,不要回头看。好的。

编辑好的。

我看到过一些关于"使用ARC不能代替了解Cocoa内存管理规则"的评论。这基本上是正确的,但理解为什么和为什么不这样做很重要。首先,如果您的所有代码都使用ARC,并且您在整个地方违反了这三个神奇的单词,那么您仍然没有问题。说起来很震惊,但你走了。ARC可能会保留一些你不想保留的东西,但它也会释放它们,所以这无关紧要。如果我今天在Cocoa教一门新课,我可能会花不到五分钟的时间来学习实际的内存管理规则,在讨论kvc命名时,我可能只会提到内存管理命名规则。有了ARC,我相信您实际上可以成为一个不错的初学者,而不必学习内存管理规则。好的。

但是你不能成为一个优秀的中级程序员。您需要了解规则,以便正确地与核心基础进行沟通,每个中间程序员需要在某个时间处理CF。您需要知道混合ARC/MRC代码的规则。当你开始乱搞void*指向id的指针(你继续需要正确地执行kvo)时,你需要知道规则。和街区…嗯,块内存管理很奇怪。好的。

因此,我的观点是,底层内存管理仍然很重要,但是在我过去花大量时间为新程序员声明和重述规则的地方,使用ARC,它正在成为一个更高级的主题。我宁愿让新开发人员从对象图的角度来思考,也不愿让他们的头脑中充满对objc_retain()的底层调用。好的。好啊。


比我的答案更好,更多的技术性答案会出现,但下面是:

  • 弧!=垃圾收集。没有运行时惩罚,它是在编译时完成的。
  • 弧也!=正如您在评论中建议的那样,自动释放所有内容。阅读文档
  • 一旦你意识到你做了多少人工参考资料管理工作,那就太棒了。
  • 用它!
  • 一个缺点是维护旧的、非ARC代码突然变得非常繁琐。


How much benefit can ARC bring to a project?

其好处是可以在很大程度上防止常见的内存管理错误。应显著减少因未能释放物体而导致的泄漏和因未能保留或过早释放物体而导致的碰撞。您仍然需要了解引用计数的内存模型,这样您就可以将引用分类为强引用或弱引用,避免保留循环,等等。

How much does garbage collection really 'cost'?

iOS中没有垃圾收集。ARC与GC类似,因为您不必手动保留或释放对象。与GC不同的是,它没有垃圾收集器。RETAIN/RELEASE模型仍然适用,只是编译器在编译时将适当的内存管理调用插入到代码中。

Have you been using ARC and if so, how have you found it so far?

如果你习惯了引用计数,这会让人有点不安,但这只是一个习惯它并学会相信编译器确实会做正确的事情的问题。它感觉像是对Objective-c 2.0所带来的属性变化的延续,这是简化内存管理的又一大步。如果没有手动内存管理调用,代码会变短,更容易阅读。

ARC唯一的问题是它在旧版本的iOS中不受支持,所以在决定采用它之前,您需要考虑到这一点。


我认为弧线是个好主意。与GC相比,你也可以吃蛋糕。我倾向于相信,MRC对记忆管理实施了一个无价的"纪律",每个人都会从中受益。但我也同意真正需要注意的问题是对象所有权和对象图(正如许多人指出的那样),而不是低级别的引用本身。

总而言之:ARC并不是一个对记忆无动于衷的自由通行证;它是一个帮助人们避免重复性任务的工具,这些任务会造成压力并容易出错,因此更好地委托给机器(在本例中是编译器)。

也就是说,我个人算是个工匠,还没有转型。我刚开始使用Git…

更新:所以我迁移了整个游戏,包括了GL库,到目前为止没有任何问题(除了Xcode4.2中的迁移助手)。如果你要开始一个新项目,就去做吧。


我遇到的唯一缺点是,如果您使用一个具有大量corefundation函数和数据的库。在MRC中,您不需要担心使用CFStringRef而不是NSString*。在ARC中,您必须指定两个交互的方式(基本桥接?释放CoreFoundation对象并将其移动到ARC?将Cocoa对象设为+1 CoreFoundation保留对象?)另外,在OSX上,它只在64位代码上可用(尽管我确实有一个头部可以解决这个问题…)。


我在几个(公认是小的)项目中使用过它,而且我只有很好的经验,从性能和可靠性两方面考虑。

需要注意的一点是,您需要学习弱引用的do:s和don:t:s,而不是导致任何引用循环。如果您自己对UI进行编码,那么如果您使用它来设置GUI,设计人员往往会自动地做好它。