由于我目前正在处理的项目中的大多数代码都是在iOS 5.0之前编写的,因此我尚未使用ARC。
我只是在想,不手动保留/释放(由此带来的结果可能是更可靠的代码)的便利是否超过了使用ARC的任何“成本”?您对ARC有什么经验,您会推荐吗?
所以:
- ARC可为项目带来多少收益?
- ARC是否具有Java垃圾回收这样的成本?
- 您是否一直在使用ARC?如果是,到目前为止,您是如何找到它的?
由于我目前正在处理的项目中的大多数代码都是在iOS 5.0之前编写的,因此我尚未使用ARC。
我只是在想,不手动保留/释放(由此带来的结果可能是更可靠的代码)的便利是否超过了使用ARC的任何“成本”?您对ARC有什么经验,您会推荐吗?
所以:
Answers:
没有缺点。用它。今天就做。它比您的旧代码更快。它比旧代码更安全。它比您的旧代码容易。这不是垃圾收集。它没有GC运行时开销。编译器将在您应该拥有的所有位置中插入并释放。但是它比您更智能,并且可以优化不需要的内容(就像它可以展开循环,消除临时变量,内联函数等)一样。
好的,现在我将告诉您一些小的缺点:
如果您是ObjC的长期开发人员,看到ARC代码时会抽搐大约一周。您将很快克服这一点。
桥接到Core Foundation代码有一些(非常)小的麻烦。有稍微在处理任何更多的并发症治疗的id
作为void*
。像C数组这样的事情id
可能需要更多的思考才能正确完成。花哨的处理ObjC va_args
也会引起麻烦。在ObjC指针上涉及数学的大多数事情都比较棘手。在任何情况下,您都不应拥有太多。
你不能把一个id
在struct
。这种情况很少见,但有时用于打包数据。
如果未遵循正确的KVC命名,并且将ARC和非ARC代码混合在一起,则将遇到内存问题。ARC使用KVC命名来制定有关内存管理的决策。如果全部是ARC代码,那么没关系,因为它将在两边都做同样的“错误”操作。但是,如果混合使用ARC /非ARC,则存在不匹配的情况。
在ObjC异常抛出期间,ARC将泄漏内存。ObjC异常应在程序终止时非常接近。如果捕获了大量的ObjC异常,则说明使用错误。使用可以解决此问题-fobjc-arc-exceptions
,但是会产生以下讨论的罚款:
在ObjC ++代码中引发ObjC或C ++异常期间,ARC不会泄漏内存,但这是以时间和空间性能为代价的。这是在尽量减少使用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使得这比实际操作困难得多。您可能应该将非ARC代码移到单独的xcodeproj中,以简化此操作。
总之,请尽快切换到ARC,并且永远不要回头。
编辑
我已经看到了一些类似的评论:“使用ARC不能代替了解Cocoa内存管理规则。” 这基本上是正确的,但了解为什么以及为什么不重要。首先,如果您所有的代码都使用ARC,并且您违反了三个魔术字在整个地方,您仍然不会有任何问题。令人震惊的说,但是你去了。ARC可能会保留一些您并不是要保留的东西,但是它也会释放它们,所以没关系。如果我今天在Cocoa上一堂新课,那么我可能在实际的内存管理规则上花费的时间不会超过五分钟,并且在讨论KVC命名时可能只会提及内存管理命名规则。借助ARC,我相信您完全可以成为一个体面的入门程序员,而无需学习任何内存管理规则。
但是您不能成为一个体面的中级程序员。您需要了解规则才能正确地与Core Foundation桥接,并且每个中级程序员都需要在某些时候处理CF。并且您需要了解ARC / MRC混合代码的规则。当您开始弄乱void*
指向的指针时,您需要了解规则id
(您仍然需要正确执行KVO)。和块...好吧,块内存管理很奇怪。
因此,我的观点是,底层的内存管理仍然很重要,但是在过去我花大量时间为新程序员说明和重新制定规则,而ARC则成为了一个更高级的主题。我宁愿让新的开发人员在对象图方面进行思考,也不愿对objc_retain()
。进行底层调用。
比我的更好,更多的技术答案会出现,但是这里是:
ARC可为项目带来多少收益?
好处是可以有效防止常见内存管理错误。因未能释放对象而导致的泄漏和因无法保留或过早释放对象而导致的崩溃应大大减少。您仍然需要了解引用计数的内存模型,以便可以将引用分类为强引用或弱引用,避免保留周期,等等。
垃圾回收真正地要多少钱?
iOS中没有垃圾回收。ARC与GC相似,因为您不必手动保留或释放对象。与GC不同的是,这里没有垃圾收集器。保留/释放模型仍然适用,只是编译器在编译时将适当的内存管理调用插入您的代码中。
您是否一直在使用ARC?如果是,到目前为止,您是如何找到它的?
如果您习惯于引用计数,这会有点令人不安,但这只是习惯于它并学会相信编译器确实会做正确的事情。感觉就像是Objective-C 2.0附带的属性更改的延续,这是简化内存管理的又一大步。没有手动的内存管理调用,您的代码将变得更短,更易于阅读。
ARC的唯一问题是,iOS的较早版本不支持ARC,因此在决定采用ARC之前,必须将其考虑在内。
我认为ARC是个好主意。与GC相比,您也可以吃蛋糕。我倾向于认为,MRC对内存管理施加了宝贵的“纪律”,每个人都将从中受益。但是我也同意,要意识到的真正问题是对象所有权和对象图(正如许多人指出的那样),而不是低级别的引用计数本身。
总结一下:ARC不是免费的通行证,它可以使内存无关紧要。它是一种工具,可帮助人们避免重复的任务,这些任务会造成压力并易于出错,因此最好委派给计算机(在这种情况下为编译器)。
就是说,我个人是一个工匠,还没有过渡。我刚开始使用Git ...
更新:因此,我迁移了我的整个游戏,包括gl库,到目前为止没有任何问题(Xcode 4.2中的迁移助手除外)。如果您要开始一个新项目,请继续。
我已经在几个(非常小)的项目中使用了它,并且我在性能和可靠性方面都只有很好的经验。
一个小小的注意事项是,如果您自己编写UI,则需要学习弱引用的do:s和not:s不会引起任何引用循环,设计人员往往会做得很好如果您使用它来设置您的GUI,它会自动运行。