Почему я должен писать [выпуск anView], anView = nil;а не [выпуск anView];?

StackOverflow https://stackoverflow.com/questions/805915

Вопрос

Где-то я читал это - относительно предупреждений о нехватке памяти и отказа от невидимого представления со всеми его подпредставлениями (= целым пером, я думаю), вы должны сделать это:

-(void)dealloc {
    [anView release], anView = nil;
    [someImageView release], someImageView = nil;

    [super dealloc];
}

скорее, чем

-(void)dealloc {
    [anView release];
    [someImageView release];

    [super dealloc];
}

В чем причина привязки этих указателей к нулю (= «нет объекта») после того, как я вызываю выпуск?Дайте угадаю:Какой-то другой метод мог по какой-то причине сохранить представление (есть ли какой-нибудь пример, когда это могло произойти?), затем происходит событие DidReceiveMemoryWarning, и вы освобождаете целое представление пера+, которое в настоящее время не видно (т.е.в мультипросмотровом приложении).Как только пользователь захочет снова увидеть это представление, вы снова быстро загрузите наконечник, а затем:Он загружает все виды, подключает розетки и БАХ!Другие ваши сохраненные представления теперь висят без какого-либо указателя где-то одиноко в блоке памяти, что приводит к большой и глубокой утечке памяти, пока ваше приложение не выйдет из строя.

Правильно Неправильно?

Это было полезно?

Решение

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

- (void) dealloc
{
    self.retainedProperty1 = nil;
    self.retainedProperty2 = nil;
    self.copiedProperty = nil;
    self.assignedProperty = nil;
}

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

Редактировать:Я должен отметить, что ваши свойства не могут быть доступны только для чтения, иначе по очевидным причинам вы получите ошибки компилятора :)

Другие советы

Этот принцип более общий, чем UIView.действительно, он более общий, чем Objective-C/Cocoa -release метод.Это справедливо и для C malloc()/free() функции памяти.

Когда вам больше не нужен объект или какая-либо зона памяти, сначала вы отпускаете/освобождаете его.Затем, чтобы убедиться, что вы не будете использовать его снова, вы очищаете средства доступа к этому объекту или зоне памяти, назначая nil к объекту или NULL к указателю памяти.

Какой-то другой метод мог по какой-то причине сохранить представление.

Если вы не вызываете dealloc самостоятельно, он вызывается только тогда, когда счетчик сохранения становится равным нулю.

Обратите внимание, что в Objective-C отправка сообщения nil «объект» (часто) совершенно прекрасен.Это будет нет остановите вашу программу, но сообщение просто проигнорируется.Однако вы не можете отправить сообщение освобожденному объекту, что приведет к сбою.

Итак, следующее приведет к ошибке:

[anView release];
[anView doSomething];

Но на самом деле это нормально:

[anView release];
anView = nil;
[anView doSomething];

Это дело вкуса, но, учитывая вышеизложенное, вы, возможно, предпочтете аварийно завершить свою программу, а не задаваться вопросом, почему doSomething не выполняется...

Смотрите также Отправка сообщений в ноль от Apple Введение в язык программирования Objective-C 2.0.

Метод -dealloc вызывается, когда объект освобождается, и после этого никакие другие методы объекта выполняться не будут.Следовательно, установка любой переменной экземпляра в ноль не имеет никакого эффекта за пределами этого объекта.

Если бы вы выпускали объект (без использования установщика) где-то еще в классе, было бы важно установить для переменной экземпляра значение nil, чтобы код в другом месте не отправлял сообщение на этот адрес.

Я часто использую этот шаблон:

- (void) showHelp: (id) sender
{
    if (helpController == nil)
    {
        helpController = [[HelpController alloc] initWithNibName: @"Help" bundle: [NSBundle mainBundle]];
    }
    [self presentModalViewController: helpController animated: YES];    
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
    [helpController release];
    helpController = nil;
}

Практически везде, где я выделяю модальный или иначе «временный» контроллер представления.Таким образом, он сохраняется, если он мне снова понадобится, но исчезает, если памяти становится мало.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top