Вопрос не в том, использовать или не использовать авто-релиз, потому что в некоторых случаях авто-релиз - единственный путь, через который вы можете пройти. Вопрос должен звучать так: « Почему бы не использовать autorelease для всех объектов вместо использования retain и release? ».
Чтобы ответить на этот вопрос, вы должны сначала узнать, как правильно использовать autorelease. Допустим, у вас есть класс с двумя свойствами: firstName и lastName. Для каждого есть геттер и сеттер. Но вам также нужен метод, который бы возвращал fullName путем объединения этих двух строк в совершенно новую строку:
- (NSString *) fullName {
NSString str = [[NSString alloc]initWithFormat:@"%@ %@", firstName, lastName];
// this is not good until we put [str autorelease];
return str;
}
Что не так с этой картинкой? Счетчик ссылок в возвращаемой строке равен 1, поэтому, если вы не хотите, чтобы утечка произошла, вызывающий должен освободить ее, когда он закончил. С точки зрения вызывающего, он просто запросил значение свойства fullName
. Он не знает о том факте, что он получил совершенно новый объект, который он должен выпустить после использования, а не какую-то ссылку на строку NSSt, внутренне принадлежащую классу!
Если мы поместим [str release]
перед возвратом, строка будет уничтожена, а метод вернет мусор! Здесь мы используем [str autorelease]
, чтобы пометить объект для освобождения в более позднее время (как правило, когда обработка события завершена). Таким образом, вызывающий объект получает свой объект, и ему не нужно беспокоиться о том, должен он его отпустить или нет.
Соглашение состоит в том, чтобы вызывать autorelease для нового объекта, прежде чем метод вернет его вызывающей стороне. Исключением являются методы с именами, которые начинаются с alloc
, new
или copy
. В таких случаях вызывающие абоненты знают, что для них создан совершенно новый объект, и они обязаны вызывать функцию освобождения для этого объекта.
Замена релиза с помощью автоматического выпуска - плохая идея, так как объекты очень быстро накапливаются и забивают память, особенно в циклах. Ресурсы на iPhone ограничены, поэтому для минимизации перегрузки памяти вы обязаны освободить объект, как только закончите с ним.