Цель C init - PullRequest
       39

Цель C init

1 голос
/ 12 марта 2011

Отказ от ответственности, я новичок в Objective C. Но я не могу найти это объясненным.Я видел два способа реализации init:

- (id)init {

  if ([super init]) {
    return self;
  } else {
    return nill;
  }

}

и

- (id)init {
    if (self = [super init]) {
      // do your init business here
    } 
    return self;
}

, поэтому предположим, что у меня есть:

myObj = [[MyObject alloc] init];

, где класс MyObject является подклассомNSObject.во втором примере init не возвращает инициализированную версию NSObject?так что myObj ... как бы он знал, что это такое?Разве это не думает, что это был NSObject, а не MyObject?

Ответы [ 2 ]

3 голосов
/ 12 марта 2011

1) Первая версия просто неверна.self всегда должно присваиваться значение, возвращаемое инициализатором super, потому что init<...> из super может вернуть другой объект при инициализации (это не является необычным, кстати).Вторая версия на самом деле является «официальным» способом реализации init<...> методов.

2) «не будет ли она думать, что это скорее NSObject, чем MyObject».myObj - это экземпляр 'NSObject' и экземпляр 'MyObject'.В этом весь смысл наследства.

1 голос
/ 12 марта 2011

Я просто хочу знать, под капотом, как он это делает.

Это довольно просто.99,9% всех классов, которые вы когда-либо напишите, будут наследовать от NSObject в некотором роде.В инициализаторах вы должны вызывать инициализатор super и назначать его self.В конце концов, [super init] будет вызывать -[NSObject init]. Согласно документации , это реализовано так:

- (id)init {
    return self;
}

Так что технически , если вы наследуете непосредственно от NSObject, вы, вероятно, можете невыполните присвоение self = [super init];, потому что вы знаете (и вам это гарантировано), что это эквивалентно: self = self;, что бессмысленно.В любом случае, вы должны оставить это в целях согласованности.

Однако, как только вы начнете продвигаться дальше по цепочке наследования, и особенно , когда вы наследуете от непрозрачных классов (то есть классачей .m файл у вас нет), то все становится неясным.Возможно, вы столкнетесь с классом, чей назначенный инициализатор выглядит примерно так:

- (id) initWithFoo:(id)aFoo {
  if ([aFoo isSuperFast]) {
    [self release];
    return [[SuperFastFooWrapper alloc] initWithFoo:aFoo];
  }
  self = [super init];
  if (self) {
    _foo = [aFoo retain];
  }
}

Это не так часто, но это случается.В этом случае мы уничтожаем self ([self release], чтобы сбалансировать вызов alloc, который непосредственно предшествовал этому), и вместо этого возвращаем другой объект.

...