Preparing for ARC
There are two ways to support ARC in an iOS project. One way is to use an ARC-enabled template to create the project. Another is to have Xcode adapt an existing project for ARC.
Suppose you want to start a new iOS project. Launch Xcode and choose New Project from the File menu. On the new assistant dialog (Figure 5), select a project template (in this example, Single View Application), and click Next to view the project options. Enter the project name, company ID, and class prefix in the fields provided. Then click to set the check-box Use Automatic Reference Counting (Figure 6). Click Next to view the project location. Set the location and the source repository (optional), then click Create to create the project itself.
Figure 5.
Figure 6.
To verify if ARC is enabled, select the project icon from the Groups and Files pane in the project window (Figure 7). Click on Build Settings from the Target Settings toolbar, then click All underneath that toolbar. Scroll down and locate the settings group Apple LLVM computer 3.0 Language. Look for the entry labeled Objective-C Automatic Reference Counting it should have a value of Yes.
Figure 7.
What if you want to adapt an existing iOS project to ARC? Open the project into Xcode and click on the Edit menu. From the Refactor submenu (Figure 8), choose Convert to Objective-C ARC... This brings up another assistant dialog summarizing the steps to be taken.
Figure 8.
Click Next to see a list of build targets (Figure 9). Select a target and click Precheck to start refactoring. If refactoring fails, Xcode will alert the user, and it will list the refactor errors on the project window.
Figure 9.
If the refactor succeeds, Xcode goes into compare mode (Figure 10). The assistant dialog splits into three panes. The left pane displays the affected files, with the first file selected. The middle pane show the original source text, the right pane shows the modified source. Review the proposed changes and click Save to commit them or Cancel to dispose of them. Make sure to have a code repository in place, however. Otherwise, you will be unable to revert the project files to their pre-ARC state.
Figure 10.
What if you want to exclude some project files from ARC? In this case, click to clear the checkbox next to each file while Xcode is in compare mode (see Figure 10). If the file was added to a refactored project, select the project icon from the Groups and Files pane. Click Build Phases on the Target Settings pane, and scroll down to the group Compile Sources (Figure 11). Click on the group header and select which files to exclude. Then click into the Compile Flags column and enter -fno-objc-arc into the modal dialog. Click Done to set the flag, which should appear next to each file.
Figure 11.
Guidelines for ARC
When writing ObjC code from scratch, you should ensure the code is compatible with ARC. That code must give ARC the clues it needs to do its tasks. Otherwise, it may insert statements in the wrong spots, or worse, it may report false errors in the code.
Here are some guidelines for writing ARC-compatible code. These are compiled from the official Apple docs and from blog articles listed at the end of this article.
- Let ARC decide how and when to retain and release objects.
As stated earlier, the ARC front-end catches any explicitretainandreleasemessages. It will report them as errors, and you will have to remove them manually to let the project compile. So never send aretainorreleasemessage to an ObjC object. Never check the object'sretainstatus with aretainCountmessage because that message is no longer reliable. Also, do not use the directive@selectorto invoke the object'sretainandreleasemethods.
As for@propertyaccessors, declare them without the attributesassign,copy, orretain. Let ARC decide on which attribute to give each accessor. - Let ARC manage the autorelease pool and its objects.
Again, the ARC front-end catches any explicit autorelease messages. Make sure to exclude these messages in your ObjC code.
Also, do not useNSAutoreleasePoolto create the pool. Instead, use the@autoreleasedirective to mark the location and scope of the pool. This tells the front-end to insert statements that create and dispose of pools optimized for ARC.
Consider the sample code in Listing Three.
Listing Three
void main() { NSArray *tArgs = [[NSProcessInfo processInfo] arguments]; unsigned tCnt, tLmt = [tArgs count]; @autorelease { for (tCnt = 0; tCnt < tLmt; tCnt++) { @autorelease { NSString *tDat; NSString *tNom; tNom = [tArgs objectAtIndex:tCnt]; tDat = [[[NSString alloc] initWithContentsOfFile:tNom] autorelease]; // Process the file, creating and // autoreleasing more objects } } // Do more tasks, creating and autoreleasing // more objects } // Do whatever cleanup is needed exit (EXIT_SUCCESS); }
Here, themain()entry function uses two autorelease pools. The first pool appears near the start of the function (line 7) and stays active until the function ends (line 28). Any objects marked for autorelease by the function go to this pool.
The second pool appears at the start of afor-loop cycle (line 11-23). As each cycle ends, it disposes of the pool and creates a new one in its place. Objects marked for autorelease during each loop go to this pool, not to the first one.


