LuckyLuke
LuckyLuke

Reputation: 49097

Assign the return object of the superclass to self

I have read many posts about this now but I do not still understand it. I would appriciate an answer rather than a link because I probably already have read it.

if (self = [super init]) {

}

return self;

When I am calling the [super init] I know I am calling the method on "self"(the objects address) but I am starting the "method-search" in the superclass. When this returns I assign the object type id to self...This is where I am getting lost.

Am I assigning "self" as an initialized object up to the point of the superclass to self..?

I understand that I am doing this check to stop the initializing if the superclass implementation of the initializer returns nil however I dont understand what I am assinging to self....I thought self was an address to the current object in memory.

Thanks in advance

Upvotes: 1

Views: 272

Answers (3)

Edward Ashak
Edward Ashak

Reputation: 2421

lets break this into smaller chunks:

1- when your calling [super init] your making your super class run its init function first so it can initialize your object that your inheriting, normally that would be NSObject or any superclass that you decided to extend. the super init functions will return self at the end of that process, just like your doing in your init function

2- when you do the assignment: self = [super init] your actually assigning that return value from your super into your own.

3- the if around that assignments actually evaluates the success/failure of the super init call, cause if it failed you would have got a nil back and the assignments would have been nil to self. so evaluating nil will return false and you wont run your init code.

4- eventually you also return self (nil if failed / actuall object if it succeeded)

hope that clears it.

Upvotes: 1

danyowdee
danyowdee

Reputation: 4698

There are two reasons, why that assignment is important:

  1. The designated initializer (di) of the superclass may return nil if initialization fails.
    In this case, without the assignment of its return value to self, you would end up in a state that is completely unsafe — most likely, your superclass's di will have released the object pointed at by self in order to not leak memory.
    If you went on using that instance and you're lucky you should see a crash in the not so distant future. If you're not that lucky, you're going to mess with some other object's internal state and lose or corrupt user-data before your program crashes.
  2. There are quite a few classes in Cocoa(Touch) — the class-clusters like NSString and NSArray probably being the most prominent examples — that may return a different instance from their di.
    The pointer you will receive from [NSString alloc] for example will almost definitely not be the same you'll obtain from a subsequent call to initWithFormat:@"Hello %@!", @"foo".

Upvotes: 2

zoul
zoul

Reputation: 104065

The assignment has always seemed a bit hacky to me. Its main point is that the superclass might want to return some other instance than the one that was initially allocated:

id foo = [[Foo alloc] init];

@interface Foo : SuperFoo {…}
@implementation Foo

- (id) init
{
    self = [super init];
    if (!self)
        …;
    return self;
}

@interface SuperFoo : NSObject {…}
@implementation SuperFoo

- (id) init
{
    [self release];
    return [OtherClass alloc];
}

This is crazy indeed, but the fact is that [super init] might return an object different from the previous self. See Mike Ash’s blog post, that should make things super clear.

Upvotes: 4

Related Questions