fuzzygoat
fuzzygoat

Reputation: 26223

Adding a custom initWith?

If I create a custom initWith for an object do I essentially include the code I would add should I want to override init?

-(id) init {
    self = [super init];
    if (self) {
        NSLog(@"_init: %@", self);
    }
    return(self);
}

e.g.

-(id) initWithX:(int) inPosX andY:(int) inPosY {
    self = [super init];
    if(self) {
        NSLog(@"_init: %@", self);
        posX = inPosX;
        posY = inPosY;
    }
    return(self);
}

gary

Upvotes: 51

Views: 52666

Answers (5)

dbachrach
dbachrach

Reputation: 341

I'd suggest creating one main initializer that handles most of the work. You can then create any number of other initializers that all call this main one. The advantage of this is if you want to change the initialization process, you'll only have to change one spot. It might look like this:

-(id) initWithX:(float)x {
    if (self = [super init]) {
        /* do most of initialization */
        self.xVal = x;
    }
    return self;
}

-(id) init {
    return [self initWithX:0.0f];
}

In this example initWithX: is our main initializer. The other initializer (init) simply calls initWithX: with a default value (in this case 0).

Upvotes: 10

ohho
ohho

Reputation: 51931

For modern Objective-C ...

UDFile.h

#import <Foundation/Foundation.h>

@interface UDFile : NSObject

@property (nonatomic, strong) NSString *name;

- (instancetype)initWithName:(NSString *)name NS_DESIGNATED_INITIALIZER;

@end

UDFile.m

#import "UDFile.h"

@implementation UDFile

- (instancetype)initWithName:(NSString *)name {
    self = [super init];
    if (self) {
        _name = [name copy];
    }
    return self;
}

- (instancetype)init {
    return [self initWithPathname:@""];
}

Upvotes: 5

stefanB
stefanB

Reputation: 79790

You can create one designated initializer that accepts all parameters that you want to make available in initialization.

Then you call from your other -(id)init your designated initializer with proper parameters.

Only the designated initializer will initialize super class [super init].

Example:

- (id)init
{
    return [self initWithX:defaultX andY:defaultY];
}

- (id)initWithPosition:(NSPoint)position
{
    return [self initWithX:position.x andY:position.y];
}


- (id)initWithX:(int)inPosX andY:(int)inPosY
{
    self = [super init];
    if(self) {
        NSLog(@"_init: %@", self);
        posX = inPosX;
        posY = inPosY;
    }
    return self;
}

The designated initializer is -(id)initWithX:andY: and you call it from other initializers.

In case you want to extend this class you call your designated initializer from subclass.

Upvotes: 97

dreamlax
dreamlax

Reputation: 95335

Sometimes, you want to reuse some initialisation code and modify the behaviour only slightly for specific initialisers. In this case, I do the following:


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

    // These values are always initialised this way
    ivar1 = 10;
    ivar2 = @"HellO";
    ivar3 = [[NSMutableArray alloc] initWithCapacity:10];
    ivar4 = 22;

    return self;
}

- (id) initWithIvar4:(int) aValue
{
    // call -init on self, which will call -init on super for us, and set
    // up ivar1, ivar2, ivar3, and ivar4.
    self = [self init];
    if (!self) return nil;

    // Change ivar4 from the default 22 to whatever aValue is.
    ivar4 = aValue;

    return self;
}

Upvotes: 2

Benjamin Cox
Benjamin Cox

Reputation: 6120

Yes, that's exactly how I do it. One slight change will cut out a line of code:

 if (self = [super init]) {

As opposed to:

 self = [super init];
 if(self) {

Upvotes: 6

Related Questions