Silver challenge: best practice for multiple inits?


#1

For this challenge all I did was get the new method “initWithItemName:(NSString *)name serialNumber:(NSString *)sNumber” to call the designated initialiser…

- (instancetype) initWithItemName:(NSString *)name
                     serialNumber:(NSString *)sNumber
{
 
   return [self initWithItemName:name
                  valueInDollars:0
                    serialNumber:sNumber];
}

And now I’m wondering if it’s best to follow the pattern set out in the book? i.e. Should I get the “initWithItemName:(NSString *)name” method to call the method that I just created (and not directly call the designated initialiser for the BNRItem class) or is it ok as is? Because the program runs fine both ways it seems.


#2

I had the same thought as you and I don’t really think it matters all that much.
What you would accomplish if you call the initializer you just created is that your code would be a tiny bit shorter. But for as far as performance goes it would have to call 2 other init methods as opposed to one. Of course performance really isn’t an issue in this case, so I suppose it’s just a matter of aesthetics really.


#3

I think calling the designated initializer in each of your initializers is preferable. Why would you want to “chain” your initializers (i.e. have init call initWithItemName: which calls initWithItemName:serialNumber: which calls…)?


#4

It doesn’t matter too much, as pointed out, but I normally chain up like so:

- (instancetype)initWithItemName:(NSString *)name valueInDollars:(int)value serialNumber:(NSString *)serial
{
    self = [super init];
    
    if (self) {
        // ...
    }
    
    return self;
}

- (instancetype)initWithItemName:(NSString *)name serialNumber:(NSString *)serial
{
    return [self initWithItemName:name valueInDollars:0 serialNumber:serial];
}

- (instancetype)initWithItemName:(NSString *)name
{
    return [self initWithItemName:name serialNumber:@""];
}

The slight advantage to this approach is we have exactly one location where we define the “default” value for serialNumber (@"" in initWithItemName:) and valueInDollars (0 in initWithItemName:serialNumber:). So if we ever need to change what this value is, we can just change it in one location.

As mentioned, there really is not a right way, as long as all of your initializers are directly or indirectly calling the designated initializer.