Авторелиз против Релиза

Учитывая два сценария, какой код лучше всего подходит и почему?

Автовыпуск

loginButton = [[[UIBarButtonItem alloc] initWithTitle:@"Login" 
                                                style:UIBarButtonItemStylePlain 
                                                target:self 
                                                action:@selector(loginButtonClicked:)]
                                                autorelease];
self.navigationItem.rightBarButtonItem = loginButton;

or

Выпуск

loginButton = [[UIBarButtonItem alloc] initWithTitle:@"Login" 
                                                style:UIBarButtonItemStylePlain 
                                                target:self 
                                                action:@selector(loginButtonClicked:)];
self.navigationItem.rightBarButtonItem = loginButton;
[loginButton release];

person Sheehan Alam    schedule 05.05.2010    source источник


Ответы (7)


Кажется, существует клеймо против использования авторелиза (т. е. я предпочитаю выпускать, когда это возможно), поэтому я обычно иду вторым путем. Но поскольку здесь вы не находитесь в цикле, освобождение сейчас и автоматическое освобождение позже будут иметь точно такой же эффект (поскольку другой объект сохранил loginButton, он не будет освобожден ().

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

person Brian    schedule 05.05.2010
comment
На устройстве с малым объемом памяти, таком как iPhone, лучше явно освобождать, когда это возможно. Это также упрощает отладку странных ошибок EXC_BAD_ACCESS, поскольку явный выпуск означает, что вы контролируете срок службы объекта. - person Alex Reynolds; 06.05.2010
comment
@Alex, в данном случае это буквально не имеет значения - объект сохраняется сразу после создания. Все, что произойдет, это то, что счетчик ссылок будет уменьшен на единицу... какая разница, произойдет ли это сразу или когда-нибудь позже? - person Carl Norum; 06.05.2010
comment
Это не имеет значения, только если вы никогда не переназначаете self.navigationItem.rightBarButtonItem до того, как будет выпущен пул автоматического освобождения. - person JeremyP; 06.05.2010

Для вашего примера это не имеет значения. Лично я, вероятно, использовал бы первый случай. Это позволит вам позже добавлять модификации или код отладки, не беспокоясь о перемещении строки [loginButton release].

person Carl Norum    schedule 05.05.2010
comment
Понятия не имею, наверное, просто кто-то, кто достаточно сильно чувствует, что autorelease — это какое-то зло во всех случаях на iPhone. Я даю вам +1, потому что вы действительно рассматриваете дело, которое он опубликовал, а не просто делаете общее заявление. И потому что я чувствую то же, что и ты. - person Quinn Taylor; 06.05.2010
comment
Что ж, использование первого случая приводит к сбою моего приложения. -[UIBarButtonItem isSystemItem]: message sent to deallocated instance 0x2095f2c0 - person rohan-patel; 06.04.2013

Как говорит Карл, в вашем случае все будет в порядке. Это потому, что объект UIBarButtunItem остается в памяти, потому что одна ссылка на него хранится внутри self.navigationItem (при условии, что вы объявили это свойство с помощью @property (retain).). Таким образом, обычная критика использования пула автоосвобождения, что он хранит ненужные объекты в памяти до конца текущего цикла событий, здесь не применима.

person Yuji    schedule 05.05.2010

Поскольку у вас очень ограниченный бюджет памяти на iPhone, предпочтительным способом должен быть явный выпуск. Таким образом, объекты не задерживаются до тех пор, пока пул автоосвобождения не будет опустошен во время цикла выполнения, и вы сможете максимально уменьшить занимаемый объем памяти.

person Claus Broch    schedule 05.05.2010
comment
Эта критика справедлива только для временных одноразовых объектов, которые не выживут в той области, в которой они были созданы. Когда вы создаете объект, который хранится в течение длительного времени, это не имеет большого значения, так как объект все равно будет рядом, независимо от того, освобождаете ли вы его или автоматически освобождаете. В таких случаях это скорее вопрос предпочтений. - person Quinn Taylor; 06.05.2010

Поскольку navigationItem сохраняет его, они становятся идентичными. С точки зрения стиля автовыпуск предпочтительнее для возвратов из методов, которые не говорят alloc или copy в своем имени, но в остальном это зависит от вас. Если бы объект не сохранялся отдельно, освобождение освободило бы память быстрее.

Проблема в стиле кода установки ссылки на nil после выпуска является связанным вопросом.

person Jeremy Murray    schedule 05.05.2010

Когда вы отправляете сообщение -autorelease объекту, вы добавляете его в список, и он получит сообщение -release при освобождении пула автоматического освобождения. Вся цель -autorelease состоит в том, чтобы предоставить вам способ сбалансировать ваши удержания и выпуски, когда что-то еще может хотеть объект, который вы выпускаете, но вы этого не делаете. В описанной вами ситуации второй пример, который вы привели, лучше.

person NSResponder    schedule 05.05.2010

Хотя в представленном сценарии эти два случая идентичны, использование релиза (reference ) по сравнению с автовыпуском. Поэтому, когда есть строгие требования к производительности, используйте выпуск

person amar    schedule 06.11.2013