Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 968
Dan Avatar asked Nov 03 '10 01:11

Dan


2 Answers

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

like image 136
Lou Franco Avatar answered Nov 16 '22 21:11

Lou Franco


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.

like image 21
Chuck Avatar answered Nov 16 '22 20:11

Chuck