问题描述
我还没有使用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?
所以:
- ARC可以为项目带来多少好处?
- ARC是否有类似垃圾收集的成本?
- 有你一直在使用ARC,如果是的话,到目前为止你是如何找到它的?
推荐答案
那里没有缺点。用它。今天就这样做。它比旧代码快。它比旧代码更安全。它比旧代码更容易。这不是垃圾收集。它没有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-arrays这样的东西可以多花一些时间来考虑做正确的事情。处理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
放进去结构
。这是相当罕见的,但有时它用于打包数据。
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.
在ObjC异常抛出期间,ARC将泄漏内存。 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:
在ObjC ++代码中抛出ObjC或C ++异常时,ARC不会泄漏内存,但这会以时间和空间性能为代价。这是为了最大限度地减少使用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,这是一个耻辱,但相当容易解决。 __弱
指针很棒,但它们不是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代码的规则。当你开始搞乱 void *
指向 id
的指针时,你需要知道规则(你还需要它)正确执行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?优缺点都有什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!