简体   繁体   中英

Designated Initializer

-(id)initWithStrAndDate: (NSString *)inString date:(NSDate *)inDate
{
  if (self = [super init])
  {
    [self setStr:inString];
    [self setDate:inDate];
  }
  return self;
}

-(id)initWithStr: (NSString *)inString
{
      return [self initWithStrAndDate:inString date:[NSDate date]];
}

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

I am not sure that I know how to use the "designated initializer". First of all isn't

return [self initWithStrAndDate:inString date:[NSDate date]];

this wrong? Shouldn't this be:

return [self initWithStrAndDate:inString date:nil];

And also why do we use 3 different initializers? I mean when do we use "-(id)init" or "-(id)initWithStr: (NSString *)inString" or the first one?

When a class has multiple initializers one, or sometimes more, of them are defined as designated initializers - these initializers must completely initialize the class and invoke a designated initializer of the super-class so that it is completely initialized.

Other initializers are called secondary initializers and must , via calls to self , end up invoking one of the designated initializers. (See Cocoa Fundamentals - Multiple initializers .)

There are two main consequences of this model:

  • You avoid code duplication and consequential errors; for most classes one initializer does all the work; and
  • When sub-classing you only need to override the super-classes designated initializers and primitive methods (the non-initializer method equivalent of designated initializers) as all other methods of the super-class end up calling these. You can of course override more methods and must to do if you need to change the behaviour (see Cocoa Fundamentals - Multiple initializers again.)

So your example is correct - 1 designated initializer and 2 secondary initializers which invoke the designated one via a call to self .

There are 3 different initializers so you can use either one of them - neither one of them is wrong, they allow you to init the class with variable data - mostly for convenience as in the end they all do the same thing.

You may init the class with specified string and date (the first and longest initializer),

or you can specify the string only and have the date be set to current time,

or you can have an empty string and current time.

note that calling:

[self init];

is equal to calling

[self initWithStr: nil];

and this in turn is equal to

[self initWithStrAndDate: nil date:[NSDate date]];

So in the end you are calling the same initializer anyway.

You have one designated initializer read the root initializer or the method that does all the work. The other initializer methods only call this root initializer with default values for the missing parameters.
You use [NSDate date] instead of nil , simply because the current date is your default value.

Which initializer you should use depends on the values you want the object to have set. If you have a string and a date, you use the one with string and date. If you don't have a date, you use the one without the date and just the string, and so on.

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