Skip navigation.
 
mlRe: self = [super init] debate.
FROM : Wade Tregaskis
DATE : Sun Feb 10 20:50:58 2008

> 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

Related mailsAuthorDate
mlself = [super init] debate. Scott Andrew Feb 10, 18:18
mlRe: self = [super init] debate. Scott Andrew Feb 10, 18:35
mlRe: self = [super init] debate. Adhamh Findlay Feb 10, 19:41
mlRe: self = [super init] debate. John Newlin Feb 10, 20:13
mlRe: self = [super init] debate. Hans van der Meer Feb 10, 20:20
mlRe: self = [super init] debate. Quincey Morris Feb 10, 20:29
mlRe: self = [super init] debate. Jens Alfke Feb 10, 20:45
mlRe: self = [super init] debate. Wade Tregaskis Feb 10, 20:50
mlRe: self = [super init] debate. Ricky Sharp Feb 10, 21:01
mlRe: self = [super init] debate. Jens Alfke Feb 10, 22:44
mlRe: self = [super init] debate. Hans van der Meer Feb 10, 23:26
mlRe: self = [super init] debate. Paul Bruneau Feb 10, 23:29
mlRe: self = [super init] debate. Uli Kusterer Feb 10, 23:40
mlRe: self = [super init] debate. Paul Bruneau Feb 11, 00:18
mlRe: self = [super init] debate. - Thanks Scott Andrew Feb 11, 00:56
mlRe: self = [super init] debate. Quincey Morris Feb 11, 02:32
mlRe: self = [super init] debate. mmalc crawford Feb 11, 02:49
mlRe: self = [super init] debate. Jens Alfke Feb 11, 03:05
mlRe: self = [super init] debate. Bill Bumgarner Feb 11, 03:28
mlRe: self = [super init] debate. Quincey Morris Feb 11, 04:35
mlRe: self = [super init] debate. Jean-Daniel Dupas Feb 11, 10:27
mlRe: self = [super init] debate. Jens Alfke Feb 11, 17:08
mlre: self = [super init] debate. Ben Trumbull Feb 11, 23:58