Подтвердить что ты не робот

Почему в Objective-C мы используем self = [super init] вместо просто [super init]?

В книге я увидел, что если подкласс переопределяет метод суперкласса, мы можем иметь

self = [super init];

Во-первых, предполагается ли это в методе подкласса init?

Во-вторых, мне интересно, почему вызов не просто

[super init];

? Я имею в виду, что во время вызова init память выделяется alloc уже (я думаю, [Foobar alloc], где Foobar - это имя подкласса. Поэтому мы не можем просто вызвать [super init] для инициализации переменные-члены? Почему мы должны получить возвращаемое значение init и присваивать self? Я имею в виду, что перед вызовом [super init], self должен указывать на допустимый патч памяти... так зачем присваивать что-то для себя снова?

(если назначить, не будет [super init] просто вернуть self существующее значение?)

4b9b3361

Ответ 1

Итак, зачем присваивать значение, возвращенному из [super init], самому себе? Смотря на типичный метод инициализации:

 - (id)initWithString:(NSString *)aString {
     self = [super init];
     if (self)
     {
         instanceString = [aString retain];
     }
     return self; }

Почему мы назначаем [super init] для себя здесь?

Причина учебника заключается в том, что [super init] разрешено выполнять одну из три вещи:

  • Вернуть собственный ресивер (указатель не изменяется) с помощью инициализируются значения унаследованных экземпляров.
  • Возвращает другой объект с инициализируются значения унаследованных экземпляров.
  • Возвращает нуль, указывая на сбой.

В первом случае присваивание не влияет на self и instanceString устанавливается в исходном объекте (строка instanceString = [aString сохранить]; может быть первой линией метод и результат будут одинаковыми).

В третьем случае инициализация завершилась неудачно. self устанавливается в nil, никаких дальнейших действий не предпринимается, и возвращается nil.

Обоснование присвоения себе связано со вторым case: если возвращаемый объект отличается, мы хотим:

instanceString = [aString retain]; which gets converted to

self->instanceString = [aString retain]; to act on the correct value,

поэтому мы должны изменить значение self, чтобы указать на этот новый объект.

надеясь, что это поможет...

От Cocoa с любовью

Ответ 2

Классическим примером возврата другого объекта из -init является реализация кластера классов - абстрактного интерфейса с несколькими конкретными исполнителями, обеспечивающих различное хранилище или алгоритмы. +[NSString alloc] возвращает экземпляр NSPlaceholderString. Инициализаторы экземпляра-заполнителя проверяют их параметры, освобождают строку-заполнитель и возвращают инициализированный экземпляр конкретного подкласса NSString.

Ответ 3

Возможно, суперкласс может решить, что объект не может быть инициализирован должным образом и возвращает nil как отказ. Если вы не назначаете nil для себя, ваш метод init будет продолжаться в предположении, что родительский класс правильно инициализировал объект.

Также возможно, чтобы родительский класс также возвращал совершенно другой объект, если он хочет.

Ответ 4

Поймите, что объект уже выделен и само указывает на память.

Теперь [super init] выполняет инициализацию.

1) Если инициализация является успешной самооценкой одного объекта перед инициализацией

2) Если инициализация - это отказ, функция init возвращает nil и self = nil. Теперь мы можем проверить, инициализирован ли объект, и если да, сделаем нашу магию с помощью этого кода

 if(self = [super init]){
  // do our magic
 }

IT так же, как мы используем imageView, мы обычно используем

UIImageView imgView = [[UIImageView alloc] init];

imgView будет иметь только значение nil, если оба параметра alloc и init будут успешными.