Не приводит ли стандартная инициализация объекта в Objective-C к утечкам памяти? - PullRequest
6 голосов
/ 03 ноября 2010

Стандартный способ создания объекта в Objective-C выглядит следующим образом:

MyClass* object = [[MyClass alloc] init];

Стандартная реализация MyClass init метода будет выглядеть примерно так:

-(id) init
{
    self = [super init];
    if(self) { /* initialize */ }
    return self;
}

Помимо некоторых изменений синтаксиса и исключая фабричные методы, кажется, что это рекомендуемый способ написать метод init и использовать его.

Насколько я понимаю, цель self = [super init]; состоит в том, чтобы обработать случай, когда [super init] терпит неудачу. Но если он потерпит неудачу и вернет ноль, не будет ли утечка памяти? Причина в том, что MyClass init вернет nil, object будет nil, больше не будет указателей, которые ссылаются на объект, выделенный с помощью [MyClass alloc] и, следовательно, нет возможности освободить его.

Это два решения, о которых я могу думать, но я не видел ни одного в обычной практике.

После вызова alloc проверьте результаты перед вызовом init:

MyClass* object = [MyClass alloc];
if(object == nil) { /*handle the error */ }
else { object = [object init]; }

Или, если [super init] не удается, освободите память. Примерно так:

-(id) init
{
    id temp = [super init];
    if(!temp) { [self release]; }
    self = temp;
    if(self) { /* initialize */ }
    return self;
}

Я не прав в этих рассуждениях? Можно утверждать, что [super init] вряд ли потерпит неудачу, но тогда зачем присваивать результаты этого self и проверять на ноль? Я был бы рад увидеть некоторые разъяснения.

Ответы [ 2 ]

6 голосов
/ 03 ноября 2010

Если [super init] хочет вернуть ноль, он также должен вызвать release для себя.

2 голосов
/ 03 ноября 2010

Метод init должен избавиться от объекта, если он решит прервать и вернуть nil.

Однако, это именно то, что охватывает if (self). self = [super init] служит другой цели: метод init может возвращать что-то, кроме объекта, которому было отправлено сообщение. Для примера из реальной жизни [NSArray alloc] возвращает фиктивный объект, а различные методы init… этого объекта возвращают реальный массив.

...