Re: self = [super init] debate.
Re: self = [super init] debate.
- Subject: Re: self = [super init] debate.
- From: Jens Alfke <email@hidden>
- Date: Sun, 10 Feb 2008 13:44:32 -0800
The real killer argument for reassigning 'self' is that the call to
[super init] might fail, returning nil. If this happens, the
superclass init method has released/dealloced the object (to avoid a
leak) so your 'self' is now a dangling pointer to freed memory. In
this case you must immediately return nil instead of doing any more
setup.
And -init methods do return nil for reasons other than out-of-memory.
For example, -[NSString initWithUTF8String:] returns NIL if the
parameter isn't valid UTF-8, and -[NSDictionary
initWithContentsOfFile:] returns nil if the file isn't found or isn't
a plist.
So the following is buggy, and will crash or corrupt memory if the
superclass's initializer ever fails:
-(id) initWithFoo: (int)foo {
[super initWithFoo: foo];
_bar = 1;
return self;
}
This is a real problem. I have run into actual bugs that were caused
by writing an initializer this way.
The following change is no help:
-(id) initWithFoo: (int)foo {
[super initWithFoo: foo];
if( self )
_bar = 1;
return self;
}
The "if(self)" check is pointless because 'self' is a local variable;
the superclass init method won't affect it. The only way to find out
if the superclass init returned nil is to actually check its return
value. The following would work:
-(id) initWithFoo: (int)foo {
if( [super initWithFoo: foo] )
_bar = 1;
return self;
}
If the superclass init fails, this will correctly avoid accessing
'self', and instead return nil. What this doesn't support, however, is
the previously-described case where the superclass initializer
succeeds but returns a different object. To support that, you actually
have to assign the return value of 'super init' to 'self'.
-(id) initWithFoo: (int)foo {
self = [super initWithFoo: foo];
if( self )
_bar = 1;
return self;
}
It's possible to coalesce the first two lines into "if( self = [super
initWithFoo: foo] )", but I avoid this because putting assignments
inside 'if' or 'while' tests is a dangerous idiom ... it's very easy
to type "==" instead of "=" and end up with a difficult-to-detect bug.
—Jens_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden