Automatic Reference Counting

Guides | Tutorial By 4 years ago

Automatic Reference Counting (ARC) has been around since iOS 5, however it has been an optional tick box when beginning a new project, and if not selected, Manual Reference Counting (MRC) is used. As of Xcode 5, the ARC tick box is missing, and all new projects start with ARC. While you can still disable ARC manually in the project”s config file, this is probably a good sign that ARC is the way to go for new projects.

Personally I”m for either. There are good things and bad things about both.

The good

– Pretty easy
– No manual memory management for Objective-C classes, a big win for group projects where it takes one rookie to mess everything up

The bad

– A slight overhead for weak ownerships (see below), probably not something noticable
– While memory is handled for Objective-C classes, any C or C objects created (CGImageRef etc etc) must be manually released or freed. I list this as bad because I think with the ease of ARC, people may develop bad habits and forget to do these things in the small circumstances when it”s required

New concepts

Weak and strong

Before ARC, a parent would be retained and a child would be assigned. This would prevent a retain loop. In ARC, a retained object would now be considered “strong”, and an assigned object considered “weak”. For the most part these will act the same, however weak has the added bonus of nullifying itself automatically whenever that object is deallocated. Note that some of the foundation classes don”t support weak ownerships, and others such as NSNotificationCenter and KVO still need to be unobserved manually.

All properties assume a strong ownership unless otherwise specified. Variables (ivars) default to strong as well. Copy implies strong ownership but the object is still copied, just as before.

Assign can still be used for properties, but acts as an unretained object that will not be nullified for you automatically.

Retaining, releasing, autoreleasing and deallocating

In ARC the retain, release, autorelease and retainCount methods are all deprecated. There should be no need to call these. Dealloc can still be overridden in order to do some cleanup (removing yourself as an observer for notifications etc etc), however super does not need to be called (and will throw a compile error if tried).

An NSAutoreleasePool cannot be used, if a lot of objects are going to be created inside one cycle of the runloop, @autoreleasepool can be wrapped around the code.

Bridged casts

In order to convert between CF objects and Objective-C objects in ARC, bridging is required because none of the CF objects are managed by ARC.

In a nutshell:

When ARC needs to know that it should take ownership of the CF object getting sent to it and should handle it”s memory on your behalf (something you”d previously need to manually CFRelease), ownership should be transferred to ARC with a __bridge_transfer cast:

NSString* personName = (__bridge_transfer NSString*)ABRecordCopyCompositeName(person);
// personName released for us after it"s final use

When casting in the opposite direction, from a Objective-C object to a CF object, if the CF object is to be managed and released by you, a __bridge_retained cast is required:

NSString* animal = @"Kitty Cat";
CFStringRef feline = (__bridge_retained CFStringRef)animal;

In all other cases, a __bridge cast can be used, which is just a pointer cast with no transferring or retaining. This is usually what”s needed when no ownership is changing hands.

NSArray* colors = ...;
CGGradientRef gradient = CGGradientCreateWithColors(..., (__bridge CFArrayRef)colors, ...);
CGGradientRelease(gradient); // CF not handled by ARC

For a more in depth look at ARC, see the following:
Transitioning to ARC Release Notes, Apple documentation