Когда следует отпускать объекты в - (void) viewDidUnload, а не в -dealloc?

Что такое -(void)viewDidUnload полезно?

Могу ли я не просто передать все в -dealloc? Если представление выгрузилось, не было бы все равно -dealloc?

Ответ 1

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

Одной из наиболее важных причин его реализации является то, что подклассы UIViewController обычно также содержат ссылки на различные подматрицы в иерархии представлений. Эти свойства можно было установить через IBOutlets при загрузке из низа или программно внутри -loadView, например.

Дополнительное владение subviews с помощью UIViewController означает, что даже когда его представление удаляется из иерархии представлений и выпущено для сохранения памяти, через которое субвью также освобождается представлением, они фактически не будут освобождены, поскольку UIViewController сам по-прежнему содержит свои собственные замечательные ссылки на эти объекты. Освобождение дополнительного ресурса UIViewController от этих объектов гарантирует их освобождение и освобождение памяти.

Объекты, которые вы выпускаете здесь, обычно воссоздаются и снова устанавливаются, когда представление UIViewController равно re-loaded, либо из Nib, либо через реализацию -loadView.

Также обратите внимание, что свойство UIViewController view равно nil к моменту вызова этого метода.

Ответ 2

Как сообщает :

Он вызывается во время условий с низкой памятью, когда диспетчеру просмотра необходимо освободить свой вид и любые объекты, связанные с этим видом, чтобы освободить память.

В той же ситуации dealloc не вызывается. Этот метод доступен только в ОС3 и выше. Работа с той же ситуацией в iPhone OS 2.x была настоящей болью!

Обновление Июль 2015: Следует отметить, что viewDidUnload устарел в iOS 6, потому что "Views больше не очищаются в условиях низкой памяти и поэтому этот метод никогда не вызывается". Итак, современный совет не стоит беспокоиться об этом и использовать dealloc.

Ответ 3

Это связано с тем, что вы обычно устанавливаете @property как "(nonatomic, retain)", и как таковой создатель, созданный для вас, освобождает текущий объект, а затем сохраняет аргумент i.e.

self.property = nil;

... выполняет что-то по строкам:

[property release];
property = [nil retain];

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

Надеюсь, что это поможет.

Ответ 4

Помните, что viewDidUnload - это метод в контроллере представления, а не в представлении. Метод view dealloc вызывается при разгрузке представления, но метод диспетчера dealloc контроллера не может вызываться дольше.

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

Ответ 5

Вывод:

У View Controllers есть свойство view. Обычно кусок или фрагмент кода добавляет к этому виду другие представления. Это часто происходит внутри метода -viewDidLoad, например:

- (void)viewDidLoad {
    [super viewDidLoad];
    [self createManyViewsAndAddThemToSelfDotView];
}

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

В iPhone OS 2.2, когда -didReceiveMemoryWarning вызывается из системы, вам нужно было что-то освободить, чтобы освободить память. Вы могли бы освободить весь вид контроллера контроллера, если это имело смысл. Или просто большое потребление памяти в нем.

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that not essential, such as cached data
}

Теперь в новой ОС 3.0 существует метод -viewDidUnload, который будет вызываться из системы, когда представление было выгружено из-за низкой памяти (пожалуйста, исправьте меня: когда именно это вызвано?)

-viewDidUnload используется для выпуска всех объектов, принадлежащих как самому контроллеру представления, так и представлению. Причина. Если контроллер представления содержит ссылки на дочерние элементы представления, то есть кнопку, дочерние представления, на которые ссылаются, не будут освобождены, потому что их счетчик сохранения равен >= 1. После того, как они выпущены в -viewDidUnload, они могут освободиться из памяти.

Ответ 6

Apple устарела viewWillUnload, теперь вы можете использовать didReceiveMemoryWarning или dealloc, чтобы освободить ваши объекты.

В iOS 6 методы viewWillUnload и viewDidUnload UIViewController теперь устарел. Если вы использовали эти методы для выпуска данных используйте вместо этого метод didReceiveMemoryWarning. Вы также может использовать этот метод для публикации ссылок на представление контроллеры, если они не используются. Вам нужно будет проверить, что перед тем как это сделать, представление не находится в окне.

Ответ 7

Если контроллер вида выведен из стека контроллера навигации и не сохраняется нигде, он будет освобожден, и вместо него будет вызываться dealloc вместо viewDidUnload. Вы должны освободить представления, созданные в loadView в dealloc, но нет необходимости устанавливать переменные в nil, так как вскоре после вызова dealloc переменные больше не будут существовать.

Ответ 8

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