-1

I have created a different init method and would like that to be the designated initializer instead of the standard -init. How can I prevent client code from instantiating the class using -init?

e.g.

/* everyone must call this */
- (id)initWithInfo:(NSDictionary *)info {
  self = [super init];
  if (self) {
      _info = info;
  }

  return self;
}

/* Don't want anyone to be able to create this using init */
Boon
  • 40,656
  • 60
  • 209
  • 315
  • 2
    sidenote: your method is missing `return self;` – Guillaume Algis Jan 13 '14 at 13:30
  • and it's "designated initializer", not "default initializer". – trojanfoe Jan 13 '14 at 13:33
  • 1
    Either map `init` to another `init...` or make it throw an error. There's no way to "hide" it. – Hot Licks Jan 13 '14 at 13:33
  • How about leave the `init` alone and mention in your documentation how the object should be initialized? – Desdenova Jan 13 '14 at 13:38
  • 1
    possible duplicate of [Best way of preventing other programmers from calling -init](http://stackoverflow.com/questions/9634256/best-way-of-preventing-other-programmers-from-calling-init) or [Is it possible to make the -init method private in Objective-C?](http://stackoverflow.com/questions/195078/is-it-possible-to-make-the-init-method-private-in-objective-c?lq=1) – Matthias Bauch Jan 13 '14 at 14:01

3 Answers3

5

init comes from the hierarchy of NSObject. Every class will have init.

Hence you can't remove the method of super-class.

Also user / developer can use any other way to create a new object like new, initWith....

Anoop Vaidya
  • 46,283
  • 15
  • 111
  • 140
0

You could try this:

- (id)init 
{
  return [self initWithInfo:@{}];
}

- (id)initWithInfo:(NSDictionary *)info 
{
  self = [super init];
  if (self) 
  {
      _info = [NSDictionary dictionaryWithDictionary:info];
  }
  return self;
}
iOS Dev
  • 4,143
  • 5
  • 30
  • 58
  • 3
    How you pass data to someDictionary??? Before allocation of class? – Tirth Jan 13 '14 at 13:33
  • All the idea of the question is initializing the object with a custom dictionary and you are setting it to `nil`. – Desdenova Jan 13 '14 at 13:41
  • This approach is good when you have to do some custom initializations, but in order to initialize info dictionary, must be called `initWithInfo` method. There is nothing to be sent by calling `init` method. – iOS Dev Jan 13 '14 at 13:51
0

While you can't remove superclass initializers, you can "block" them by overriding them like this:

- (id)init
{
    NSAssert(NO, @"Use the designated initializer: -initWithInfo:");
    [self doesNotRecognizeSelector: _cmd];
    if (self = [super init])
    {
        self = nil;
    }
    return self;
}

This will at least "fail fast" (at runtime.) It'd be nice if this could be made to fail at compile time, but I don't believe there's any way to achieve that at this point.

ipmcc
  • 29,581
  • 5
  • 84
  • 147