Присвойте возвращаемый объект суперкласса себе - PullRequest
1 голос
/ 07 февраля 2011

Я прочитал много сообщений об этом сейчас, но я до сих пор не понимаю этого. Я бы оценил ответ, а не ссылку, потому что я, вероятно, уже прочитал его.

if (self = [super init]) {

}

return self;

Когда я вызываю [super init], я знаю, что вызываю метод для «self» (адрес объекта), но я запускаю «поиск метода» в суперклассе. Когда он возвращается, я присваиваю тип объекта id себе ... Вот где я заблудился.

Назначаю ли я "себя" как инициализированный объект до точки суперкласса для себя ..?

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

Заранее спасибо

Ответы [ 3 ]

4 голосов
/ 07 февраля 2011

Задание всегда казалось мне немного хакерским. Суть его в том, что суперкласс может захотеть вернуть какой-то другой экземпляр, чем тот, который был изначально выделен:

id foo = [[Foo alloc] init];

@interface Foo : SuperFoo {…}
@implementation Foo

- (id) init
{
    self = [super init];
    if (!self)
        …;
    return self;
}

@interface SuperFoo : NSObject {…}
@implementation SuperFoo

- (id) init
{
    [self release];
    return [OtherClass alloc];
}

Это действительно безумие, но факт в том, что [super init] может вернуть объект, отличный от предыдущего self. См. сообщение в блоге Майка Эша , которое должно прояснить ситуацию super.

2 голосов
/ 07 февраля 2011

Существуют две причины, почему это назначение важно:

  1. Назначенный инициализатор (di) суперкласса может вернуть nil, если инициализация не удалась.
    В этом случае безприсваивая его возвращаемое значение self, вы окажетесь в совершенно небезопасном состоянии - скорее всего, ди вашего суперкласса освободит объект, на который указывает self, чтобы не допустить утечки памяти.
    ЕслиВы продолжали использовать этот экземпляр, и вам повезло, что вы увидите аварию в не столь отдаленном будущем.Если вам не так повезет, вы будете связываться с внутренним состоянием какого-то другого объекта и терять или повреждать пользовательские данные до того, как ваша программа выйдет из строя.
  2. В Какао (Touch) довольно много классов -кластеры классов, такие как NSString и NSArray, вероятно, являются наиболее яркими примерами, которые могут возвращать другой экземпляр из своего di.
    Указатель, который вы получите, например, от [NSString alloc], почти наверняка не будет одинаковымВы получите от последующего звонка initWithFormat:@"Hello %@!", @"foo".
1 голос
/ 07 февраля 2011

позволяет разбить это на более мелкие куски:

1 - когда вы вызываете [super init] или создаете суперкласс, сначала запускается его функция init, чтобы он мог инициализировать ваш объект, который вы наследуете, обычно это будет NSObject или любой суперкласс, который вы решили расширить. функции super init возвращают себя в конце этого процесса, так же, как вы выполняете свою функцию init

2 - когда вы делаете присваивание: self = [super init] вы фактически присваиваете это возвращаемое значение из вашего super в ваше собственное.

3 - , если вокруг этих назначений фактически оценивает успех / неудачу вызова super init, потому что в случае неудачи вы получили бы nil назад, а назначения имели бы был ноль к себе. поэтому оценка nil вернет false, и вы не запустите свой код инициализации.

4- в конечном итоге вы также возвращаете себя (ноль, если произошел сбой, или активировать объект, если это удалось)

надеюсь, что это прояснит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...