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

Что -(void)viewDidUnload это хорошо для?

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

8 ответов

Решение

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

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

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

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

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

Как сказано в документации:

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

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

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

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

self.property = nil;

... делает что-то вроде:

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

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

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

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

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

Заключение:

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

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

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

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

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

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

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

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

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

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

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

Другие вопросы по тегам