- Retaining and Releasing
- Assigning to Instance Variables
- Automatic Reference Counting
- Returning Objects via Pointer Arguments
- Avoiding Retain Cycles
- Migrating to ARC
- Autorelease Pools
- Using Autoreleased Constructors
- Autoreleasing Objects in Accessors
- Supporting Automatic Garbage Collection
- Interoperating with C
- Understanding Object Destruction
- Using Weak References
- Allocating Scanned Memory
Migrating to ARC
If you are starting a new project in XCode, ARC will be the default and there is little reason not to use it. If you are working on an existing code base, then you are probably using manual reference counting. You can save some long-term development effort by moving to ARC, but it is a little bit more involved than simply flipping a compiler switch.
Clang provides a migration tool that will attempt to rewrite Objective-C code to use ARC. This can be invoked from the command line via the -ccc-arcmt-check and -ccc-arcmt-modify arguments. The first reports any things in the code that cannot be automatically translated. The second actually performs the rewriting—modifying the original file—if there are no errors.
For simple Objective-C code, the migration tool will just work. The most obvious thing that it does is remove all -retain, -release, and autorelease message sends. It will also remove the explicit [ super dealloc] from a -dealloc method: That call is now inserted automatically by the compiler. ARC automatically releases all instance variables, so you will only need to implement -dealloc at all if you are freeing malloc()’d memory or similar.
If you implement custom reference counting methods, then you will need to delete them. A common reason for this is to prevent accidental deallocation of singletons. This is less important with ARC, because programmer error is less likely to cause an object to be prematurely deleted.
The biggest problems come if you are trying to store Objective-C pointers in C structures. The simplest solution is just not to do that: Use Objective-C objects with public instance variables instead. This lets the compiler handle memory management for the object, as well as the fields.
The only time when using structures referring to Objective-C objects is considered safe is when you are passing them down the stack. The object pointers can then be __unsafe_unretained qualified without any problems, as long as they remain valid in the caller.
You will notice that you no longer have any assign properties after using the migration tool. These will be rewritten as unsafe_unretained or weak, depending on whether the deployment target that you’ve selected supports weak references. You may want to explicitly change some to unsafe_unretained if they are used for breaking simple cycles and you find weak references to be a performance problem.
The migration tool will try to insert __bridge casts where required, but these are worth checking. These casts are used to move objects in and out of ARC-managed code. In non-ARC Objective-C, you are free to do things like ( void *)someObject, because object pointers are just C pointers that you can send messages to. In ARC mode, this cast would be ambiguous because the compiler doesn’t know what the ownership semantics of void * are supposed to be, so it is rejected.
The migration tool will rewrite this as (__bridge void *)someObject, but that may not be what you want. We’ll look at these casts in more detail in the “Interoperating with C” section.