2010-02-14 4 views
20

Я, как правило, чтобы освободить свой материал в -dealloc, и теперь iPhone OS 3.0 представил этот забавный метод -viewDidUnload, где они говорят:Что именно я должен делать в viewDidUnload?

// Выпуск удержанных подвиды из основного вида. // например. self.myOutlet = nil;

So -viewDidUnload, похоже, вызывается, когда вид диспетчера представлений вызывается из памяти. И если у меня есть subviews, прикрепленные к главному виду контроллера представления, я должен выпустить этот материал только ЗДЕСЬ, но не в -dealloc, а?

Это сбивает с толку. Кроме того, что, если -dealloc вызывает выгрузку (освобождение) представления? Опять же, он будет вызывать -viewDidUnload?

Я понимаю разницу, что -viewDidUnload предназначен только для случая, когда сам вид убивается, но контроллер вида остается в памяти. И -dealloc предназначен для случая, когда все идет в корзину.

Возможно, кто-то может устранить путаницу.

+1

Аналогичный вопрос: http://stackoverflow.com/questions/1158788/when-should-i-release-objects-in-voidviewdidunload-rather-than-in-dealloc –

+0

viewDidUnload устарел в iOS 6! – whyoz

ответ

37

Цель состоит в том, чтобы «сбалансировать» управление подзаголовками. Все, что вы создаете в viewDidLoad, должно быть выпущено в viewDidUnload. Это облегчает отслеживание того, что должно быть выпущено где. В большинстве случаев ваш метод dealloc является зеркальным отображением вашего метода init, а ваш viewDidUnload будет зеркальным отображением вашего метода viewDidLoad.

Как вы указали, методы viewDid ... должны использоваться, когда само изображение загружается и выгружается. Это позволяет модели использования, в котором контроллер представления остается загруженной в память, но сам вид может быть загружен и выгружен в соответствии с требованиями:

init 
viewDidLoad 
viewDidUnload 
viewDidLoad 
viewDidUnload 
... 
dealloc 

Конечно, это не больно, чтобы освободить вещи в вашем методе dealloc, как ну, пока вы установите их на nil, когда вы отпустите их в viewDidUnload.

Следующая цитата из раздела управления памятью от Apple UIViewController documentation, описывает его более подробно:

... в iPhone OS 3.0 и выше, метод viewDidUnload может быть более подходящим местом для большинства потребностей ,

Когда возникает предупреждение с низкой памятью, класс UIViewController очищает свои представления, если он знает, что он может перезагрузить или воссоздать их позже. Если это произойдет, он также вызывает метод viewDidUnload, чтобы дать вашему коду возможность отказаться от владения любыми объектами, связанными с вашей иерархией представлений, включая объекты, загруженные файлом nib, объекты, созданные в вашем методе viewDidLoad, и объекты, созданные лениво время выполнения и добавлено в иерархию представлений. Как правило, если ваш контроллер просмотра содержит выходные данные (свойства или необработанные переменные, которые содержат ключевое слово IBOutlet), вы должны использовать метод viewDidUnload, чтобы отказаться от владения этими точками или любыми другими данными, связанными с просмотром, которые вам больше не нужны.

+0

viewDidUnload не является зеркалом viewDidLoad, поскольку метод Unload устанавливает выходные данные в nil. –

+1

Какой метод выгрузки вы имеете в виду? Я просмотрел документацию UIViewController, но не нашел метода с этим именем. Когда я описал viewDidUnload как (как правило) зеркальное отображение viewDidLoad, я имел в виду управление памятью; то есть все выделенные, скопированные или сохраненные в представленииDidLoad должны быть выпущены в viewDidUnload. IBOutlets обычно настраиваются автоматически, когда ваш файл nib загружен, поэтому даже если они установлены на нуль до вызова viewDidUnload, это не должно влиять на что-либо с точки зрения памяти. –

+0

быть четким; Я могу понять, как это может быть * возможно * столкнуться с проблемами, если вы должны выделить объект в viewDidLoad, который станет недоступным в viewDidUnload, когда все IBOutlets были установлены на nil. Это было бы убедительным доказательством плохого дизайна, однако, поскольку объект всегда должен содержать указатель на любую память, за которую он отвечает за освобождение. –

3

Как вы говорите, viewDidUnload будет вызываться, если self.view = nil, это обычно происходит, если вы получаете предупреждение о памяти. В этом методе вы должны освободить любое подзапрос основного вида, который может быть легко создан методом .xib или loadView.Вы должны выпустить любой объект данных, если вы создадите их в viewDidload или loadView и т. Д., Потому что эти методы будут снова вызваны для представления пользователю, эти данные могут быть легко воссозданы.

0

Когда вы получаете предупреждение о сохранности памяти, диспетчер viewout выгружает его, но сам не будет dealloc.
Все, что может быть легко создано, должно быть разгружено, но не модель представления.

Смежные вопросы