What Is a Convenience Constructor?

Friday, April 1st, 2011

Short answer: A convenience constructor is one that performs object allocation & initialization in one step & returns an autoreleased object to the caller.

Long answer: In Cocoa, object allocation and initialization are separate steps. Take this code for example:

NSString *string = [[[NSString alloc] init] autorelease];
NSString *string2 = [NSString string];

The second line uses a convenience constructor, but they are equivalent. Here’s a breakdown:

[NSString alloc]

allocates the correct amount of memory (depending on the number of instance variables and other runtime-need storage) on the heap for an object of the NSString class and returns a pointer to it. (Think of this as a malloc and a bzero, conceptually.)

[... init]

initializes the above object. This is where your code runs to set up the object and get it into whatever initial state it needs to be in.1

[... autorelease]

autoreleases the object. This is critical in Cocoa — memory management patterns dictate that callers should return autoreleased objects if they no longer need to hold a reference to them. A Cocoa programer will expect a method like +string to return an autoreleased object (how autorelease works is a bit out of scope).2

Why would you want this? It’s significantly simpler. to write, especially if you’re passing the object to another method and never actually holding a reference to it yourself.

I originally wrote this on Quora, and have lightly edited it to fit this space.

  1. This would be a good time to mention designated initializers. A full explanation is out of scope, but the designated initializer is the initializer that all other initializers for your class are supposed to call, to make it easier for subclassers — so they don’t have to implement a ton of initBlahBlah functions. By loose convention, the designated initializer is the one with the most parameters. 

  2. Cocoa programmers expect the returned object to be autoreleased because of the NARC rule — code only obtain an owning reference only if it sends new, alloc, retain or copy (or mutableCopy) to the object itself, otherwise the object should be autoreleased. For more information, see the memory management guide