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

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

<code>self = [super init];
</code>

Во-первых, должно ли это быть сделано в подклассе?init метод?

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

<code>[super init];
</code>

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

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

 Andreas Eriksson13 апр. 2012 г., 13:24
 Krishnabhadra13 апр. 2012 г., 13:33
@AndreasCarlbom блестящий учебник спасибо ...
 Josh Caswell13 апр. 2012 г., 19:53
возможный дубликатWhy should I call self=[super init]

Ответы на вопрос(4)

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

Решение Вопроса

So why assign the value returned from [super init] to self? Looking at a typical initializer method:

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

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

The textbook reason is because [super init] is permitted to do one of three things:

Return its own receiver (the self pointer doesn't change) with inherited instance values initialized. Return a different object with inherited instance values initialized. Return nil, indicating failure.

In the first case, the assignment has no effect on self and the instanceString is set on in the original object (the line instanceString = [aString retain]; could have been the first line of the method and the result would be the same).

In the third case, the initialization has failed. self is set to nil, no further action is taken and nil is returned.

The rationale for assigning to self is associated with the second case: if the returned object is different, we want the:

instanceString = [aString retain]; which gets converted to

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

so we have to change the value of self to point to this new object.

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

Из какао с любовью

 13 апр. 2012 г., 13:54
НИКАКОЙ объект не должен освобождаться сам ... нормальный способ сделать это - вызвать -dealloc ..
 太極者無極而生13 апр. 2012 г., 13:45
интересно ... так что еслиself указывал на выделенную память, а затемself установлен вnilтогда это как ... сделать себя каким-то фантомом? Например, если этоDuck объект, такduck указывает на действительную выделенную память с переменными-членами, но теперь, когдаself установлен вnilзатем он становится фантомом, так как сейчас у него больше нет переменных-членов (не указывающих на выделенную память), и все, что осталось, - это методы, способность запускать код без какого-либо «вещества»?

Поймите, чтоobject is already alloced and self points to a memory.

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

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

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

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

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

UIImageView imgView = [[UIImageView alloc] init];

imgView will only have non nil value if both alloc and init is succesful.

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

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

Ваш ответ на вопрос