Учитывая эти два сценария, какой код является лучшей практикой и почему?
Автовыпуск
loginButton = [[[UIBarButtonItem alloc] initWithTitle:@"Login"
style:UIBarButtonItemStylePlain
target:self
action:@selector(loginButtonClicked:)]
autorelease];
self.navigationItem.rightBarButtonItem = loginButton;
или
Выпуск
loginButton = [[UIBarButtonItem alloc] initWithTitle:@"Login"
style:UIBarButtonItemStylePlain
target:self
action:@selector(loginButtonClicked:)];
self.navigationItem.rightBarButtonItem = loginButton;
[loginButton release];
Кажется, существует клеймо против использования автоосвобождения (т.е. предпочтение отдается освобождению при любой возможности), поэтому я обычно иду вторым путем. Но поскольку вы не находитесь в цикле, освобождение сейчас и автоосвобождение позже будет иметь точно такой же эффект (поскольку другой объект сохранил loginButton, он не будет деаллоцирован()ed).
Но я должен отметить, что большинство моих утечек памяти вызвано тем, что я забываю добавить строку освобождения, так что, вероятно, было бы лучше просто добавить автоосвобождение сразу.
Так как у вас очень ограниченный бюджет памяти на iPhone, предпочтительным способом должно быть явное освобождение. Таким образом, объекты не задерживаются до тех пор, пока пул автоматического освобождения не опустеет во время цикла выполнения, и вы сможете сохранить как можно меньший объем памяти.
Для вашего примера это не имеет значения. Лично я бы, вероятно, использовал первый случай. Это позволит вам добавлять модификации или отладочный код позже, не беспокоясь о перемещении строки [loginButton release]
.
Поскольку элемент навигации сохраняет его, они в конечном итоге идентичны. С точки зрения стиля, авторелиз предпочтительнее для возвратов от методов, которые не говорят alloc или copy в своем имени, но в противном случае это за вами. Если объект не был сохранен отдельно, освобождение быстрее освободило бы память.
Код-Проблема стиля установки ссылки на ноль после выпуска является смежным вопросом.
В вашем случае, как говорит Карл, подойдет любой из вариантов. Это происходит потому, что объект UIBarButtunItem
остается в памяти, поскольку одна ссылка на него хранится внутри self.navigationItem
(при условии, что вы объявили это свойство с @property (retain)
). Поэтому обычная диатриба против использования пула autorelease, что он держит ненужные объекты в памяти до конца текущего цикла событий, здесь не применима.
Когда вы отправляете объекту сообщение -autorelease
, вы добавляете его в список, и он получит сообщение -release
при освобождении пула авторелизов. Вся цель -autorelease
состоит в том, чтобы предоставить вам способ сбалансировать ваши удержания и релизы, когда что-то еще может хотеть объект, который вы отпускаете, но вы этого не делаете. В ситуации, которую вы описываете, второй пример, который вы привели, лучше.