nonopolarity
nonopolarity

Reputation: 150996

Why in Objective-C, we use self = [super init] instead of just [super init]?

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

Answers (4)

Ankit Srivastava
Ankit Srivastava

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:

  1. Return its own receiver (the self pointer doesn't change) with inherited instance values initialized.
  2. Return a different object with inherited instance values initialized.
  3. 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...

From Cocoa with Love

Upvotes: 11

user23743
user23743

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

Krishnabhadra
Krishnabhadra

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

mttrb
mttrb

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

Related Questions