Favor Objective-C factory methods (or remember to release)

how-to
May 25, 20113 mins

When Java came out and I began to spend virtually all my time building Java applications, I naively figured the days of manual memory management were gone (after all, Java has garbage collection!). Fast forward to now. The popularity of the iPhone and iPad have propelled C (really, Objective-C) back into the spotlight. And with Objective-C, the return of manual memory management (along with borderline extreme code verbosity).

Manual memory management isn’t too terribly difficult as it turns out — it just requires you pay attention, especially when you alloc objects. That is, alloc calls, for the most part, should usually be followed somewhere, in scope, with a release call.

Objective-C, however, has quite a few handy factory methods that handle memory aspects like retain counts nicely. Accordingly, you don’t have to explicitly release factory created objects — in fact, if you do, you’ll get nasty errors later when some section of code attempts to use it!

For example, in the code below, I’m creating two objects — an instance of NSMutableArray and <a href="<a href="https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/Reference/Reference.html%23//apple_ref/occ/cl/NSDictionary">http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Fo...</a>">NSDictionary</a> — both are alloc‘ed and init‘ed. In the ensuing code, the array instance is added to the NSDictionary and then that dictionary is passed along to NSNotificationCenter (code left out). Consequently, I must remember to release them (and thereby decrement their retain counts) after the handoff to NSNotificationCenter.

NSMutableArray *array = [[NSMutableArray alloc]init];
//...fill the array with objects
NSDictionary *dictionary = [[NSDictionary alloc] init];
[dictionary setObject:array forKey:APP_LIST_ARRAY_KEY];
//....add to NSNotificationCenter
[array release];
[dictionary release];

I can, however, make my life a bit easier by leveraging some of NSDictionary‘s factory methods, such as dictionaryWithObject:forKey, which initializes a new instance of NSDictionary containing one item (there’s a corresponding method to add multiple items too).

NSMutableArray *array = [[NSMutableArray alloc]init];
//...fill the array with objects
NSDictionary * dictionary =
  [NSDictionary dictionaryWithObject:array forKey:APP_LIST_ARRAY_KEY];
//....add to NSNotificationCenter
[array release];

Note in the code above, I’m freed from the responsibility to release my dictionary instance. Many core Objective-C classes have these factory-like methods, such as <a href="<a href="https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html">http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Fo...</a>">NSString</a>‘s initWithFormat.

Using these methods can reduce the burden of manually managing memory, but certainly doesn’t obviate it. Can you dig it, man?

andrew_glover

When Andrew Glover isn't listening to “Funkytown” or “Le Freak” he enjoys speaking on the No Fluff Just Stuff Tour. He also writes articles for multiple online publications including IBM's developerWorks and O'Reilly’s ONJava and ONLamp portals. Andrew is also the co-author of Java Testing Patterns, which was published by Wiley in September 2004; Addison-Wesley’s Continuous Integration; and Manning’s Groovy in Action.

More from this author