简体   繁体   中英

Objective-C Object Init

I am still a bit confused by Objective-C object initialisation. Im used to nice clean object inheritance in other languages like (don't kill me) ActionScript.

Here is an example, and I would like to know if (a) its the correct way of doing it, (b) why doesn't init get called when I call initWithLevel ?

- (id) init {
    self = [super init];
    if (self != nil) {
        // Code to create game background.
        // Code to create game board.
    }
    return self;
}

- (id) initWithLevel:(NSDictionary*)level {
    self = [super init];
    if (self != nil) {
        // Code to populate game board
    }
    return self;
}

A method will be called only if you call it (except delegates/notifications, it'll be called according to the events) !!!

You are calling initWithLevel not init .

You need to write a separate method for the initialization like:

- (id) init
{
    return [self initWithLevels:nil];
}

- (id) initWithLevel:(NSDictionary*)level
{
    self = [super init];
    if (self != nil)
    {
        [self configureGameboard:level];
    }
    return self;
}

- (void)configureGameboard:(NSDictionary*)level
{
   // Code to create game background.
   // Code to create game board.
}

Refer Designated Initializer for more info.

(a) its the correct way of doing it ?

if the initWithLevel is the designated initializer for your class, then yes it's the correct way you are doing it but you should add other initialisation in the same methode.

like this :

- (instancetype) initWithLevel:(NSDictionary*)level {
        self = [super init];
        if (self != nil) {
         // Code to create game background.
          // Code to create game board.
           // Code to populate game board
        }
        return self;
    }

elsewhere you should call your designated initializer like this :

- (instancetype) initWithLevel:(NSDictionary*)level {
    self = [self init];
    if (self != nil) {

        // Code to populate game board
    }
    return self;
}

and in your init ( designated initializer ):

- (instancetype) init {
    self = [super init];
    if (self != nil) {
        // Code to create game background.
        // Code to create game board.
    }
    return self;
}

(b) why doesn't init get called when i call initWithLevel ?

Because in your initWithLevel method you are calling the super's init and not the self's init .

if your initWithLevel is the disignated initializer, you can also add an Exception to the init method to avoid creating a game without level. something like this :

- (instancetype) init {
    self = [super init];
    if (self != nil) {
       @throw [NSException exceptionWithName:@"WallSafeInitialization"
                                       reason:@"Use initWithLevel: not init"
                                     userInfo:nil];

    }
    return self;
}

From Cocoa Core Competencies :

The Designated Initializer

The initializer of a class that takes the full complement of initialization parameters is usually the designated initializer. The designated initializer of a subclass must invoke the designated initializer of its superclass by sending a message to super. The convenience (or secondary) initializers—which can include init—do not call super. Instead they call (through a message to self) the initializer in the series with the next most parameters, supplying a default value for the parameter not passed into it. The final initializer in this series is the designated initializer.

So according to Apple's documentation, your initialization methods should be chained together as follows:

- (id)init {
    return [self initWithLevel:nil]; // Consider passing a default dictionary instead of nil.
}

// Designated initializer
//
- (id)initWithLevel:(NSDictionary *)level {
    self = [super init];
    if (self != nil) {
        // Code to populate game board
    }
    return self;
}

Your init implementation could provide a more meaningful argument than nil if it makes sense in the context of your app -- for example a dictionary of game board values for level 1 as a default value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM