Возвращая ноль в init в коде Objective C - PullRequest
31 голосов
/ 02 декабря 2010

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

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

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

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

Ответы [ 2 ]

46 голосов
/ 02 декабря 2010

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

В частности, если у вас есть ошибка в инициализаторе, вы 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 указывает, что экземпляр исчез.Утечки нет, и все счастливы.

Это также допустимый шаблон (предположим, что 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, чтобы сделать что-то странное.

0 голосов
/ 02 декабря 2010

Обычно вам позвонят

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

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

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

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

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