我还没有使用 ARC,因为我目前正在处理的项目中的大部分代码都是在 iOS 5.0 之前编写的.
I've yet to use ARC, since the majority of the code in the project I'm working on at the moment was written pre-iOS 5.0.
我只是想知道,不手动保留/释放的便利(以及由此产生的更可靠的代码?)是否超过使用 ARC 的任何成本"?您对 ARC 有哪些体验,您会推荐它吗?
I was just wondering, does the convenience of not retaining/releasing manually (and presumably more reliable code that comes as a result?) outweigh any 'cost' of using ARC? What are your experiences of ARC, and would you recommend it?
所以:
没有缺点.用它.今天就去做.它比您的旧代码更快.它比您的旧代码更安全.它比您的旧代码更容易.这不是垃圾收集.它没有 GC 运行时开销.编译器在您应该拥有的所有地方插入保留和释放.但它比你更聪明,可以优化掉那些实际上不需要的(就像它可以展开循环、消除临时变量、内联函数等)
There is no downside. Use it. Do it today. It is faster than your old code. It is safer than your old code. It is easier than your old code. It is not garbage collection. It has no GC runtime overhead. The compiler inserts retains and releases in all the places you should have anyway. But it's smarter than you and can optimize out the ones that aren't actually needed (just like it can unroll loops, eliminate temporary variables, inline functions, etc.)
好的,现在我将告诉你一些小缺点:
OK, now I will tell you about the small downsides:
如果你是一个长期的 ObjC 开发者,当你看到 ARC 代码时,你会抽搐大约一周.你会很快克服这个问题的.
If you're a long-time ObjC developer, you will twitch for about a week when you see ARC code. You will very quickly get over this.
桥接到 Core Foundation 代码有一些(非常)小的复杂性.处理将 id
视为 void*
的任何事情都会稍微复杂一些.id
的 C 数组之类的事情可能需要更多的思考才能正确完成.ObjC va_args
的花哨处理也会引起麻烦.大多数涉及 ObjC 指针上的数学运算的事情都比较棘手.无论如何,你不应该有太多这样的事情.
There are some (very) small complications in bridging to Core Foundation code. There are slightly more complications in dealing with anything that treats an id
as a void*
. Things like C-arrays of id
can take a little more thinking about to do correctly. Fancy handling of ObjC va_args
can also cause trouble. Most things involving math on an ObjC pointer is trickier. You shouldn't have much of this in any case.
您不能将 id
放入 struct
.这种情况相当少见,但有时用于打包数据.
You cannot put an id
in a struct
. This is fairly rare, but sometimes it's used to pack data.
如果您没有遵循正确的 KVC 命名,并且将 ARC 和非 ARC 代码混合在一起,则会出现内存问题.ARC 使用 KVC 命名来决定内存管理.如果都是 ARC 代码,那没关系,因为它会在双方都做同样的错误".但如果它是 ARC/非 ARC 的混合,那就是不匹配.
If you did not follow correct KVC naming, and you intermix ARC and non-ARC code, you will have memory problems. ARC uses KVC naming to make decisions about memory management. If it's all ARC code, then it doesn't matter because it will do it the same "wrong" on both sides. But if it's mixed ARC/non-ARC then there's a mismatch.
ARC 将在 ObjC 异常抛出期间泄漏内存.ObjC 异常应该非常接近程序终止的时间.如果您捕获了大量的 ObjC 异常,则说明您使用它们不正确.这可以使用 -fobjc-arc-exceptions
解决,但会招致下面讨论的惩罚:
ARC will leak memory during ObjC exception throws. An ObjC exception should be very close in time to the termination of your program. If you're catching a significant number of ObjC exceptions, you're using them incorrectly. This is fixable using -fobjc-arc-exceptions
, but it incurs the penalties discussed below:
ARC 不会在 ObjC++ 代码中抛出 ObjC 或 C++ 异常期间泄漏内存,但这是以时间和空间性能为代价的.这是尽量减少使用 ObjC++ 的众多原因中的另一个.
ARC will not leak memory during ObjC or C++ exception throws in ObjC++ code, but this is at the cost of both time and space performance. This is yet another in a long list of reasons to minimize your use of ObjC++.
ARC 根本无法在 iPhoneOS 3 或 Mac OS X 10.5 或更早版本上运行.(这使我无法在许多项目中使用 ARC.)
ARC will not work at all on iPhoneOS 3 or Mac OS X 10.5 or earlier. (This precludes me from using ARC in many projects.)
__weak
指针在 iOS 4 或 Mac OS X 10.6 上无法正常工作,这很遗憾,但很容易解决.__weak
指针很棒,但它们不是 ARC 的第一卖点.
__weak
pointers do not work correctly on iOS 4 or Mac OS X 10.6, which is a shame, but fairly easy to work around. __weak
pointers are great, but they're not the #1 selling point of ARC.
对于 95% 以上的代码,ARC 非常出色,完全没有理由避免使用它(前提是您可以处理操作系统版本限制).对于非 ARC 代码,您可以逐个文件传递 -fno-objc-arc
.不幸的是,Xcode 使这比在实践中应该做的要困难得多.您可能应该将非 ARC 代码移动到单独的 xcodeproj 以简化此操作.
For 95%+ of code out there, ARC is brilliant and there is no reason at all to avoid it (provided you can handle the OS version restrictions). For non-ARC code, you can pass -fno-objc-arc
on a file-by-file basis. Xcode unfortunately makes this much harder than it should be to do in practice. You should probably move non-ARC code into a separate xcodeproj to simplify this.
总之,尽快切换到 ARC,永远不要回头.
In conclusion, switch to ARC as soon as you can and never look back.
编辑
我已经看到了一些类似使用 ARC 不能替代了解 Cocoa 内存管理规则"的评论.这大部分是正确的,但重要的是要了解为什么以及为什么不这样做.首先,如果您的所有代码都使用 ARC,并且您违反了三个神奇词到处都是,你仍然没有问题.令人震惊的说,但你去.ARC 可能会保留一些您并不打算保留的东西,但它也会释放它们,所以这无关紧要.如果我今天在 Cocoa 中教授一门新课程,我可能会在实际的内存管理规则上花费不超过五分钟的时间,而且在讨论 KVC 命名时我可能只会提到内存管理命名规则.有了 ARC,我相信你完全可以在不学习内存管理规则的情况下成为一个体面的初级程序员.
I've seen a couple of comments along the lines of "using ARC is no substitute for knowing the Cocoa memory management rules." This is mostly true, but it's important to understand why and why not. First, if all of your code uses ARC, and you violate the Three Magic Words all over the place, you'll still have no problems. Shocking to say, but there you go. ARC might retain some things that you didn't mean it to retain, but it'll release them as well, so it'll never matter. If I were teaching a new class in Cocoa today, I'd probably spend no more than five minutes on the actual memory management rules, and I'd probably only mention the memory management naming rules while discussing KVC naming. With ARC, I believe you could actually become a decent beginning programmer without learning the memory management rules at all.
但是你不能成为一个像样的中级程序员.您需要了解规则才能正确地与 Core Foundation 桥接,并且每个中级程序员都需要在某些时候处理 CF.并且您需要了解混合 ARC/MRC 代码的规则.当您开始使用指向 id
的 void*
指针(您仍然需要正确执行 KVO)时,您需要了解规则.还有块......好吧,块内存管理很奇怪.
But you couldn't become a decent intermediate programmer. You need to know the rules in order to bridge correctly with Core Foundation, and every intermediate programmer needs to deal with CF at some point. And you need to know the rules for mixed-ARC/MRC code. And you need to know the rules when you start messing around with void*
pointers to id
(which you continue to need to perform KVO correctly). And blocks... well, block memory management is just weird.
所以我的观点是,底层内存管理仍然很重要,但我过去常常花费大量时间为新程序员陈述和重申规则,而 ARC 正在成为一个更高级的话题.我宁愿让新开发人员从对象图的角度来思考,而不是让他们的头脑充满对 objc_retain()
的底层调用.
So my point is that the underlying memory management is still important, but where I used to spend significant time stating and restating the rules for new programmers, with ARC it is becoming a more advanced topic. I'd rather get new developers thinking in terms of object graphs rather than fill their heads with the underlying calls to objc_retain()
.
这篇关于ARC还是不ARC?优缺点都有什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!