Reputation: 150996
In a book, I saw that if a subclass is overriding a superclass's method, we may have
self = [super init];
First, is this supposed to be done in the subclass's init
method?
Second, I wonder why the call is not just
[super init];
? I mean, at the time of calling init
, the memory is allocated by alloc
already (I think by [Foobar alloc]
where Foobar
is the subclass's name. So can't we just call [super init]
to initialize the member variables? Why do we have to get the return value of init
and assign to self
? I mean, before calling [super init]
, self
should be pointing to a valid memory allocation chuck... so why assigning something to self again?
(if assigning, won't [super init]
just return self
's existing value?)
Upvotes: 13
Views: 3250
Reputation: 12405
So why assign the value returned from [super init] to self? Looking at a typical initializer method:
- (id)initWithString:(NSString *)aString {
self = [super init];
if (self)
{
instanceString = [aString retain];
}
return self; }
Why do we assign [super init] to self here?
The textbook reason is because [super init] is permitted to do one of three things:
- Return its own receiver (the self pointer doesn't change) with inherited instance values initialized.
- Return a different object with inherited instance values initialized.
- Return nil, indicating failure.
In the first case, the assignment has no effect on self and the instanceString is set on in the original object (the line instanceString = [aString retain]; could have been the first line of the method and the result would be the same).
In the third case, the initialization has failed. self is set to nil, no further action is taken and nil is returned.
The rationale for assigning to self is associated with the second case: if the returned object is different, we want the:
instanceString = [aString retain]; which gets converted to self->instanceString = [aString retain]; to act on the correct value,
so we have to change the value of self to point to this new object.
hoping this helps...
Upvotes: 11
Reputation:
A classic example of returning a different object from -init
is in implementing a class cluster - an abstract interface with multiple concrete implementers providing different storage or algorithms. +[NSString alloc]
returns an instance of NSPlaceholderString
. The initialisers of the placeholder instance inspect their parameters, release the placeholder string and return an initialised instance of a concrete NSString
subclass.
Upvotes: 3
Reputation: 34265
Understand that the object is already alloced and self points to a memory.
Now [super init] does the initialization part.
1) If initialization is successful self points to same object before initialization
2) If initialization is failure init function returns nil and self = nil. Now we can check whether object is initialized and if yes do our magic by this code
if(self = [super init]){
// do our magic
}
IT is just like we use an imageView, we normally use
UIImageView imgView = [[UIImageView alloc] init];
imgView will only have non nil value if both alloc and init is succesful.
Upvotes: 2
Reputation: 8345
It is possible the superclass might decide the object can't be initialised properly and return nil as a failure. If you don't assign nil to self your init method will carry on under the assumption that the parent class has correctly initialised the object.
It is also possible for the parent class to also return a completely different object if it wants.
Upvotes: 2