Я пытаюсь научиться удерживать / освобождать. Я понимаю, что они совпадают. Но я не знаю, когда мне нужно сохранять ссылки.

-(void)sampleMethod:(RandomClass *) obj {
    [obj  retain];
    // Do stuff to object...
    [obj release];
}

Нужно ли сохранять (и тем самым освобождать) obj?

Я беспокоюсь о том, что obj уйдет. Следует ли из этого, что вы должны (если) как можно скорее сохранить ссылочные параметры в функции? Как насчет промежутка времени между вызовом функции и первой инструкцией функции?

Благодарность!

3
DrFloyd5 26 Авг 2011 в 23:33

2 ответа

Лучший ответ

Короткий ответ; используйте ARC.

Ответ Джо более-менее правильный. Пока этого не произойдет.

Как правило, нет необходимости сохранять аргументы или возвращаемые значения из других методов. Однако результирующий код работает только по совпадению и соглашению, а не путем алгоритмического анализа.

Рассмотреть:

NSString *foo = [aMutableArray objectAtIndex: 5];
[aMutableArray removeObjectAtindex: 5];
[someTextField setTextValue: foo];

БУМ !

Ваш код только что разбился. Может быть (сбой не произойдет, если foo будет постоянной строкой или случится быть сохраненным чем-то другим, или произойдет быть сохраненным / автоматически выпущенным в другом месте).

Технически это должно быть:

NSString *foo = [aMutableArray objectAtIndex: 5];
[foo retain];
[aMutableArray removeObjectAtindex: 5];
[someTextField setTextValue: foo];
[foo release];

То есть foo следует сохранять в момент, когда он входит в область видимости, и выпускать в тот момент, когда он больше не используется в области видимости. Или вы можете [[foo retain] autorelease];, но автоспускное давление может быть проблемой (обычно это не так, но может быть).

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

5
bbum 26 Авг 2011 в 21:27

Вам не нужно беспокоиться о том, что передаваемый объект исчезнет, ​​поэтому нет необходимости его сохранять. Правильное управление памятью * гарантирует, что объект будет жить в течение всего срока действия вашего метода, потому что он будет находиться в том же потоке, что и вызывающий, поэтому пул автозапуска для этого потока не должен истощаться, и вызывающий не может освободить объект до тех пор, пока ваш метод вернулся. Это справедливо даже для таких методов, как performSelectorInBackground, потому что они сохранят аргумент.

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

5
Joe 26 Авг 2011 в 21:10