Является ли возвратный авто-релиз ошибкой в ​​цели c? - PullRequest
7 голосов
/ 17 февраля 2010

Я новичок в цели c и пытаюсь понять, как / когда вызывается autorelease. Я понимаю простой случай использования:

- (void) foo {
    Bar *b = [[[Bar alloc] init] autorelease];
    [self doSomething:b];
  }

А как насчет следующего случая - это ошибка, потому что объект будет немедленно освобожден после выхода из области действия makeBar?

-(Bar*) makeBar
{
    return [[[Bar alloc] init] autorelease];
}

Что если вызывающий абонент удерживает?

Bar *b = [[self makeBar] retain];

Спасибо, -Эрик

Ответы [ 2 ]

7 голосов
/ 17 февраля 2010

Во втором примере возвращаемый вами анонимный объект не будет освобожден, как только выполнение выйдет из области действия makeBar, но на следующей итерации цикла выполнения. Это даст вам возможность retain в любом методе, вызвавшем makeBar

Итак, ваш последний пример в порядке, так как количество сохраняемых данных не упадет ниже 0.

У вас проблемы с этим?

5 голосов
/ 17 февраля 2010
-(Bar*) makeBar
{
    return [[[Bar alloc] init] autorelease];
}

Второй случай - предпочтительный способ возврата объекта Objective-C. За исключением +alloc, -copy... и -create..., метод не должен сохранять права собственности на возвращаемый объект, т. Е. Счет (сохранения) должен быть равен 0.

Однако, [[Bar alloc] init] делает объект иметь retainCount +1, чтобы его отпустить перед возвратом. Но -release немедленно освободит объект, делая метод бесполезным. Вот почему используется -autorelease - это с задержкой -release, т.е. объект будет освобожден в конце концов, но не сейчас, так что другие части кода все еще могут взаимодействовать с ним, однако счет сохранения может все еще быть сбалансированным до 0.


Bar *b = [[self makeBar] retain];

Вы должны не оставить его , если вы не хотите быть долгосрочным владельцем объекта b.

...