Почему я должен написать [выпуск anView], anView = nil; а не [выпуск anView] ;? - PullRequest
7 голосов
/ 30 апреля 2009

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

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

    [super dealloc];
}

вместо

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

    [super dealloc];
}

В чем причина заземления этих указателей на nil (= "no object") после вызова release? Позвольте мне догадаться: какой-то другой метод мог по какой-то причине -retain сохранить представление (кто-нибудь, например, когда это могло произойти?), Затем произошла вещь didReceiveMemoryWarning, и вы выпустили целое представление nib +, которое в данный момент не видно (т.е. в мультивью-приложении). Как только пользователь захочет снова увидеть этот вид, вы снова быстро загрузите перо, а затем: он загружает все виды, соединяет розетки и BANG! Ваши другие сохраненные представления теперь зависают без какого-либо указателя где-то одиноко в кирпиче памяти, вызывая большую и глубокую утечку памяти, пока ваше приложение не падает.

Right / Wrong?

Ответы [ 5 ]

14 голосов
/ 30 апреля 2009

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

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

11 голосов
/ 30 апреля 2009

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

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

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

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

[anView release];
[anView doSomething];

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

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

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

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

4 голосов
/ 01 мая 2009

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

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

2 голосов
/ 30 апреля 2009

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

- (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;
}

Практически везде, где я размещаю viewcontroller, он является модальным или иначе "временным". Таким образом, он зависает, если мне это нужно снова, но уходит, если память становится мало.

1 голос
/ 13 мая 2009

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...