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

Возврат nil в init в коде Objective C

В случае, если мы возвращаем nil в методе init, что происходит с удержанием count и кто собирается выпустить этот объект?

Как только я наберу, как только мы назовем alloc (что произойдет до init), счетчик сохранения станет 1. Теперь вызывается init и пусть по какой-то причине он не может инициализировать объект, поэтому он возвращает nil.

И похоже, что теперь у нас есть объект с сохранением count равным 1, и никто не ссылается на него, чтобы вызвать release.

Должны ли мы вызвать [self autorelease] в init для такого случая или сделать что-то еще?

4b9b3361

Ответ 1

См. Размещение и инициализация объектов в документации.

В частности, если у вас есть ошибка в инициализаторе, вы release self и возвращаете nil:

- init
{
    self = [super init];
    if (self) {
         if (... failed to initialize something in self ...) {
             [self release];
             return nil;
         }
    }
    return self;
}

Теперь рассмотрим, что происходит, когда вы вызываете [super init] и возвращает nil. Вышеупомянутый шаблон уже используется, то, что было self, было выпущено, а nil return указывает, что экземпляр отсутствует. Нет утечки, и все счастливы.

Это также допустимый шаблон (предположим, что self является экземпляром MyClass):

- init
{
    self = [super init];
    if (self) {
        ... normal initialization here ...
    } else {
        self = [MyClass genericInstanceWhenInitializationGoesBad];
        self = [self retain];
    }
    return self;
 }

Так как ожидается, что init возвращает что-то, что является retained (подразумевая привязку из +alloc), тогда [self retain], хотя он выглядит тупой, на самом деле правильный. self = [self retain] просто является дополнительной защитой, если MyClass переопределяет retain, чтобы сделать что-то странное.

Ответ 2

Обычно вы вызываете

self = [super init];
if (self == nil) {

   return nil;
}
// do some init job here
return self;

Это не ваша работа, чтобы автоопределить себя, потому что, когда у вас есть это, она уже равна нулю, поэтому даже если вы вызываете [self autorelease];, она ничего не делает.

Я думаю, что метод init NSObject должен иметь дело с объектом уже