Dan
Dan

Reputation: 105

Doesn't the standard object initialization in Objective-C lead to memory leaks?

The standard way to create an object in Objective-C looks like this:

MyClass* object = [[MyClass alloc] init];

The standard implementation of MyClass's init method would look something like this:

-(id) init
{
    self = [super init];
    if(self) { /* initialize */ }
    return self;
}

Aside from some syntax changes, and excluding factory methods, that seems to be the recommended way to write an init method, and to use it.

As I understand it, the purpose of self = [super init]; is to handle the case where [super init] fails. But if it does fail, and returns nil, wouldn't there be a memory leak? The reason being that MyClass's init will return nil, object will be nil, there will be no more pointers that reference the object allocated with [MyClass alloc], and therefore no way to release it.

These are the two solutions I can think of are, but I haven't seen either one in regular practice.

After a call to alloc, check the results before calling init:

MyClass* object = [MyClass alloc];
if(object == nil) { /*handle the error */ }
else { object = [object init]; }

Or, if [super init] fails, release the memory. Something like this:

-(id) init
{
    id temp = [super init];
    if(!temp) { [self release]; }
    self = temp;
    if(self) { /* initialize */ }
    return self;
}

Am I wrong in that reasoning? It could be argued that [super init] is unlikely to fail, but then why assign the results of it to self and check for nil? I'd be happy to see some clarification.

Upvotes: 6

Views: 628

Answers (2)

Chuck
Chuck

Reputation: 237030

An init method should get rid of the object if it decides to abort and return nil.

However, that's just what the if (self) covers. The self = [super init] serves another purpose: An init method is allowed to return something other than the object that the message was sent to. For a real-life example, [NSArray alloc] returns a dummy object, and that object's various init… methods return the real array.

Upvotes: 2

Lou Franco
Lou Franco

Reputation: 89172

If [super init] wants to return nil, it should also call release on self.

Upvotes: 6

Related Questions