The primary memory-related problem you'll still need to be aware of is retain cycles. This occurs when one object has a strong pointer to another, but the target object has a strong pointer back to the original. Even when all other references to these objects are removed, they still will hold on to one another and will not be released. This can also happen indirectly, by a chain of objects that might have the last one in the chain referring back to an earlier object.
It is for this reason that the __unsafe_unretained
and __weak
ownership qualifiers exist. The former will not retain any object it points to, but leaves open the possibility of that object going away and it pointing to bad memory, whereas the latter doesn't retain the object and automatically sets itself to nil when its target is deallocated. Of the two, __weak
is generally preferred on platforms that support it.
You would use these qualifiers for things like delegates, where you don't want the object to retain its delegate and potentially lead to a cycle.
Another couple of significant memory-related concerns are the handling of Core Foundation objects and memory allocated using malloc()
for types like char*
. ARC does not manage these types, only Objective-C objects, so you'll still need to deal with them yourself. Core Foundation types can be particularly tricky, because sometimes they need to be bridged across to matching Objective-C objects, and vice versa. This means that control needs to be transferred back and forth from ARC when bridging between CF types and Objective-C. Some keywords related to this bridging have been added, and Mike Ash has a great description of various bridging cases in his lengthy ARC writeup.
In addition to this, there are several other less frequent, but still potentially problematic cases, which the published specification goes into in detail.
Much of the new behavior, based on keeping objects around as long as there is a strong pointer to them, is very similar to garbage collection on the Mac. However, the technical underpinnings are very different. Rather than having a garbage collector process that runs at regular intervals to clean up objects no longer being pointed to, this style of memory management relies on the rigid retain / release rules we all need to obey in Objective-C.
ARC simply takes the repetitive memory management tasks we've had to do for years and offloads them to the compiler so we never have to worry about them again. This way, you don't have the halting problems or sawtooth memory profiles experienced on garbage collected platforms. I've experienced both of these in my garbage collected Mac applications, and am eager to see how they behave under ARC.
For more on garbage collection vs. ARC, see this very interesting response by Chris Lattner on the Objective-C mailing list, where he lists many advantages of ARC over Objective-C 2.0 garbage collection. I've run into several of the GC issues he describes.
If I decide to upgrade to iOS 5, do I
need to remove all [myObject retain]
and [myObject release] statements from
my code?
Yes, but XCode 4.2 includes a new "Migrate to Objective-C ARC" tool (in the Edit->Refactor menu), which does that for you. Calling dealloc is a different story. As mentioned in the comments the clang reference states that you should keep your the dealloc method:
Rationale: even though ARC destroys instance variables automatically, there are still legitimate reasons to write a dealloc method, such as freeing non-retainable resources. Failing to call [super dealloc] in such a method is nearly always a bug.
You enable ARC using a new -fobjc-arc
compiler flag. ARC is supported in
Xcode 4.2 for Mac OS X v10.6 and v10.7
(64-bit applications) and for iOS 4
and iOS 5. (Weak references are not
supported in Mac OS X v10.6 and iOS
4). There is no ARC support in Xcode
4.1.
-
If I develop a new app for iOS 5 using
ARC, will I need to implement some
sort of "retro-compatibility" checks?
I.e.: will I need to check the version
of iOS and call retain and release
accordingly? So, basically, is ARC
available for all iOS versions or just
for iOS 5?
No, because ARC does its magic on compile time and not on run time.
Instead of you having to remember when
to use retain, release, and
autorelease, ARC evaluates the
lifetime requirements of your objects
and automatically inserts the
appropriate method calls for you at
compile time. The compiler also
generates appropriate dealloc methods
for you.
Further Information on ARC: http://clang.llvm.org/docs/AutomaticReferenceCounting.html
Best Answer
It is not very intuitive how to disable ARC on MULTIPLE files, for a while I was do it one by one until a figured out how to do that.