What makes an initializer designated? - Silver challenge


#1

I’m working on the silver challenge, and it brought up a question on designated initializers. First, here’s how I solved it (incorrectly, apparently):

-(id)initWithItemName:(id)name serialNumber:(NSString *)sNumber
{
    self = [super init];
    
    if(self) {
        [self setItemName:name];
        [self setSerialNumber:sNumber];
        [self setValueInDollars:0];
        dateCreated = [[NSDate alloc] init];
    }
    
    return self;
}

Then I read this post and saw that I was wrong. However, this raised a few questions:

a. It looks to me like my code should work 100% of the time since I supplied data for dateCreated and valueInDollars. Is that true? (Though it’s clearly not a best practice since I duplicated the supplying-default-data code both here and in initWithItemName:valueInDollars:serialNumber.)

b. What technically qualifies an initializer as being the “official” designated one? Is it just whatever method is called in init? Or is it any method that supplies valid data for the “important” instance variables?

c. Is “designated initializer” a term that the compiler can understand, or is it just a programmer-enforced way of keeping your class well organized?

d. When I read the silver challenge in the book and it said “This initializer is not the designated initializer,” should that have indicated to me “don’t do any real work in here, just pass it along to another method.” ?

Thanks!


#2

I think I can respond to the questions b and c (this is from the book Programming iOS5 - Matt Neuburg),

“If a class does define initializers, one of them may be described in the documentation as the designated initializer. (There’s nothing about a method’s name that tells you it’s the designated initializer; you must peruse the documentation to find out.) For example, in the UIView class documentation, the initWithFrame: method is described as the designated initializer. A class that does not define a designated initializer inherits its designated initializer; the ultimate designated initializer, inherited by all classes without any other designated initializer anywhere in their superclass chain, is init.
The designated initializer is the initializer on which any other initializers depend, in this class or any subclasses: ultimately, they must call it. The designated initializer might have the most parameters, allowing the most instance variables to be set explicitly, with the other initializers supplying default values for some instance variables, for convenience. Or it might just be the most basic form of initialization. But in any case, it is a bottleneck through which all other initializers pass.”

b) Nothing. The documentation of a class must tells you what initializer is the designated (paragraph one).
c) The second one (paragraph two).


#3

Hi Sarah,

I think that the designated initializer is the method that is called in init, so you are right about that. This is how I solved the silver challenge:
In BNRitem.h:

- (id) initWithItemName:(NSString *)name serialNumber:(NSString *)sNumber;
Basically it is the same as the method initWithItemName:valueInDollars:serialNumber:, but without valueInDollars.
In BNRitem.m:

- (id)initWithItemName:(NSString *)name serialNumber:(NSString *)sNumber { self = [super init]; if (self) { [self setItemName:name]; [self setSerialNumber:sNumber]; dateCreated = [[NSDate alloc] init]; } return self; }
I tested the initializer in main.m:

BNRItem *item = [[BNRItem alloc]initWithItemName:@"zomaar een item" serialNumber:@"djhfgds"]; [items addObject:item]; NSLog(@"%@", [items objectAtIndex:[items count]-1]);
When I run it, the last log is:

Perhaps someone from the BNR can give us the correct answer.


#4

My take would be that for form and convention - for consistency in code, One initializer is selected as the designated one. Whomever wrote the code originally gets to say which one that is.

Any other initializers must call the designated initializer as part of their method.

While your code may work, it is not following form in the same way that method names may still work with a capital letter at the front, but it is not done. Many of these lessons appear to be teaching so that the student can work as part of a team.


#5

As you suspected and others in this thread have explained, the designated initializer is simply an accepted best practice. If you prefer another technique, you’re free to use it.

When the challenge said “This initializer is not the designated initializer,” it indicated to me “don’t repeat operations performed in the designated initializer. Instead, have the new initializer call the designated initializer.”