Re: self = [super init] debate.
Re: self = [super init] debate.
- Subject: Re: self = [super init] debate.
- From: Wade Tregaskis <email@hidden>
- Date: Sun, 10 Feb 2008 11:50:58 -0800
As i get ready to teach non-cocoa programmers in my company about
cocoa programming, and having read Will Shipley's blog, Is the
above the way to teach writing an initializer? I see Will, and a
few others, say no [super init] will initialize self in its code
there is no reason to assign self. Yet all code and docs I see have
similar code.
Initialisers do not have to - and often don't - return self. They
are free to release self and return nil, or a different object, which
can even be a different class (though it's considered rather poor
form to return an object which isn't at least an instance or subclass
of the class who's initialiser is doing this magic).
It's important to recognise that, if init fails, you're supposed to
call [self release] and return nil, because typical code is:
MyClass *woot = [[MyClass alloc] init];
If you just return nil without releasing, you've just leaked
yourself. So, ultimately the test for nil from [super init] is very
often necessary, and is a good coding style. Good coding style in
the sense that it will prevent your program from crashing.
Now, since we're all here already, and you've gotten me started, you
must endure all of it. :P So, truth be told, if you have a hierarchy:
A -> B
A -> C
A's initialiser, when called by say B, could hypothetically release
self, allocate an object of class C, and return that. If you want to
be really defensive in your coding, you could write:
self = [super init];
if ((nil != self) && [self isKindOfClass:[MyClass class]]) {
...
}
return self;
I've never seen anyone actually write that, though. Typically your
initialiser will return either nil, or an object of the same lineage
(or a further subclass thereof) of the original object. When you
start considering scenarios like {A, B, C} above, things can get
pretty silly very quickly. And generally when people start doing
things like this, it's because they've decided that transparent class
clusters would be really cool, and I always wonder if such dubious
practices are wise anyway... the official Apple line in such cases,
anyway, is don't subclass class clusters, so if you take that as
gospel this is a moot point.
And as Wil points out (http://www.wilshipley.com/blog/2005/07/self-
stupid-init.html) if your superclass' initialiser is funky because it
returns singletons (or similar) - which is the most common case of
this sort of thing - then you have issues with re-initialising
existing instances (which if nothing else will leak, because
virtually no-one releases/frees existing ivars in their
initialisers). So you'd have to then write:
id newSelf = [super init];
if (self == newSelf) {
...
} else {
[self release];
self = newSelf;
}
return self;
However, that's assuming super always returns either self or an
existing, fully-initialised instance, which as noted previously
doesn't have to be the case...
Generally, protecting against nil should be quite sufficient, as
noted, and in the few cases where a class does do funky voodoo in its
initialisers, it should document as such and explain exactly what it
could hypothetically do, so you can write your subclasses appropriately.
[[ pre-emptive retort: some people argue that you shouldn't worry
about initialisers returning nil because that means you're out of
memory and your program is hosed anyway... this is complete crap -
even aside from the fact that an initialiser returning nil could mean
any of numerous things - and many programs are designed to - and will
quite successfully - recover from such situations... iff they have
proper checks in place and don't dereference NULL immediately ]]
Wade
_______________________________________________
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