Make Better Things

I like to make better things.

Automatic Reference Counting (ARC) in Xcode 4.2

Xcode 4.2 now includes a new feature called Automatic Reference Counting aka. ARC which automates memory management for Objective-C objects. ARC makes memory management much easier, greatly reducing the chance that your program will have memory leaks. First, Xcode reviews your project to determine whether there are items that cannot be converted (and that you must therefore change manually). Then, Xcode rewrites your source code to use ARC.

ARC works by adding code at compile time to ensure that objects live as long as necessary, but no longer. Conceptually, it follows the same memory management conventions as manual reference counting, by adding the appropriate retain, release, and autorelease method calls for you.

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.

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. In general, if you’re only using ARC the traditional Cocoa naming conventions are important only if you need to interoperate with code that uses manual reference counting.

A complete and correct implementation of a Person class might look like this:

@interface Person : NSObject
@property (nonatomic, strong) NSString *firstName;
@property (nonatomic, strong) NSString *lastName;
@property (nonatomic, strong) NSNumber *yearOfBirth;
@property (nonatomic, strong) Person *spouse;

@implementation Person
@synthesize firstName, lastName, yearOfBirth, spouse;

Using ARC, you could implement a contrived method like this:

- (void)contrived {
    Person *aPerson = [[Person alloc] init];
    [aPerson setFirstName:@"William"];
    [aPerson setLastName:@"Dudney"];
    [aPerson:setYearOfBirth:[[NSNumber alloc] initWithInteger:2011]];
    NSLog(@"aPerson: %@", aPerson);

ARC takes care of memory management so that neither the Person nor the NSNumber objects are leaked.

You could also safely implement a takeLastNameFrom: method of Person like this:

- (void)takeLastNameFrom:(Person *)person {
    NSString *oldLastname = [self lastName];
    [self setLastName:[person lastName]];
    NSLog(@"Lastname changed from %@ to %@", oldLastname, [self lastName]);

ARC ensures that oldLastName is not deallocated before the NSLog statement.

ARC Enforces New Rules
To work, ARC imposes some new rules that are not present when using other compiler modes. The rules are intended to provide a fully reliable memory management model; in some cases, they simply enforce best practice, in some others they simplify your code or are obvious corollaries of your not having to deal with memory management. If you violate these rules, you get an immediate compile-time error, not a subtle bug that may become apparent at runtime.

  • You cannot explicitly invoke dealloc, or implement or invoke retain, release, retainCount, or autorelease.The prohibition extends to using @selector(retain), @selector(release), and so on.

    You may implement a dealloc method if you need to manage resources other than releasing instance variables. You do not have to (indeed you cannot) release instance variables, but you may need to invoke [systemClassInstance setDelegate:nil] on system classes and other code that isn’t compiled using ARC.

    Custom dealloc methods in ARC do not require a call to [super dealloc] (it actually results in a compiler error). The chaining to super is automated and enforced by the compiler.

    You can still use CFRetain, CFRelease, and other related functions with Core Foundation-style objects (see “Managing Toll-Free Bridging”).

  • You cannot use NSAllocateObject or NSDeallocateObject.You create objects using alloc; the runtime takes care of deallocating objects.
  • You cannot use object pointers in C structures.Rather than using a struct, you can create an Objective-C class to manage the data instead.
  • There is no casual casting between id and void *.You must use special casts that tell the compiler about object lifetime. You need to do this to cast between Objective-C objects and Core Foundation types that you pass as function arguments. For more details, see “Managing Toll-Free Bridging”.
  • Cannot use NSAutoreleasePool objects.ARC provides @autoreleasepool blocks instead. These have an advantage of being more efficient than NSAutoreleasePool.
  • You cannot use memory zones. There is no need to use NSZone any more—they are ignored by the modern Objective-C runtime anyway.

To allow interoperation with manual retain-release code, ARC imposes some constraints on method and variable naming:

You cannot give a property a name that begins with new.

Category: iPhone, xcode

Tagged: , , , ,

Leave a Reply