Відповіді:
На додаток до того, що вже було зазначено, я хотів детальніше зупинитися на логіці -viewDidUnload
.
Однією з найважливіших причин його реалізації є те, що UIViewController
підкласи зазвичай також містять власні посилання на різні підгляди в ієрархії перегляду. Ці властивості можна було встановити, наприклад, під IBOutlets
час завантаження з ручки або програмно всередині -loadView
.
Додаткове право власності на підпогляди UIViewController
означає, що навіть коли його погляд буде видалено з ієрархії подання та звільнено для збереження пам’яті, завдяки якій субпрегляди також вивільняються поданням, вони фактично не будуть розміщені, оскільки UIViewController
сам все ще містить власні видатні зберігаючи посилання на ці об’єкти. Вивільнення UIViewController
додаткового права власності на ці об'єкти гарантує, що вони будуть розміщені, а також звільнять пам'ять.
Об'єкти, які ви випускаєте тут, зазвичай відтворюються і встановлюються знову, коли UIViewController
перегляд є re-loaded
, або від Nib, або за допомогою реалізації -loadView
.
Також зауважте, що UIViewController
view
властивість знаходиться nil
до моменту виклику цього методу.
Як зазначено в документації :
Він викликається під час низької пам’яті, коли контролеру перегляду необхідно звільнити його перегляд та будь-які об’єкти, пов’язані з цим видом, щоб звільнити пам'ять.
У тій же ситуації , dealloc
це НЕ називається. Цей метод доступний лише в ОС3 та вище. Справа з такою ж ситуацією в iPhone OS 2.x справжній біль!
Оновлення липня 2015 року : Слід зазначити, що viewDidUnload
в iOS 6 було застаріло, оскільки "Перегляд більше не очищається в умовах низької пам'яті, і цей метод ніколи не застосовується". Отже, сучасна порада не турбуватися про це і користуватися dealloc
.
Це тому, що ви, як правило, встановлюєте @property
як "(nonatomic, retain)"
і як такий сетер, який створений для вас, вивільняє поточний об'єкт, а потім зберігає аргумент, тобто
self.property = nil;
... робить щось відповідно до:
[property release];
property = [nil retain];
Тому ви вбиваєте двох птахів одним каменем: управління пам’яттю (звільнення існуючого об’єкта) та призначення покажчика до нуля (оскільки надсилання будь-якого повідомлення нульовому покажчику поверне нуль).
Сподіваюся, що це допомагає.
Пам’ятайте, що viewDidUnload
це метод у контролері перегляду, а не у поданні. Метод подання dealloc
буде викликаний, коли вигляд завантажується, але метод контролера подання dealloc
може бути викликаний не пізніше.
Якщо ви отримаєте попередження про низьку пам’ять, і ваш погляд не відображається, що відбудеться, наприклад, кожного разу, коли ви використовуєте UIImagePickerController, щоб користувач міг сфотографуватися, ваш погляд буде завантажений і після цього потрібно буде перезавантажитись.
Висновок:
Контролери перегляду мають властивість перегляду. Зазвичай нитка або фрагмент коду додають цьому виду інші види. Це трапляється часто в методі -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's not essential, such as cached data
}
Тепер у новій ОС 3.0 є метод -viewDidUnload, який буде викликаний із системи, коли представлення вивантажено через низьку пам'ять (будь ласка, виправте мене: коли саме це викликається?)
-viewDidUnload використовується для звільнення всіх об'єктів, які належали як самому контролеру перегляду, так і перегляду. Причина: Якщо контролер перегляду містить посилання на дочірнє уявлення, тобто на кнопку, переглянуті дочірні погляди не будуть звільнені, оскільки їх кількість збереження становить> = 1. Після звільнення в -viewDidUnload вони можуть звільнитися з пам’яті.
Apple застаріло viewWillUnload, тепер ви повинні використовувати didReceiveMemoryWarning або dealloc, щоб випустити ваші об'єкти.
В iOS 6 методи viewWillUnload та viewDidUnload UIViewController тепер застарілі. Якщо ви використовували ці методи для звільнення даних, використовуйте замість цього метод didReceiveMemoryWarning. Цей метод також можна використовувати для випуску посилань на вигляд контролера перегляду, якщо він не використовується. Вам потрібно буде перевірити, що перегляд не знаходиться у вікні, перш ніж це зробити.
Якщо контролер перегляду вискакує з стека контролера навігації і не зберігається більше ніде, він буде розміщений, і dealloc буде викликаний замість viewDidUnload. Ви повинні випустити представлення, створені в loadView в dealloc, але не потрібно встановлювати змінні на нуль, тому що незабаром після dealloc буде викликано змінних більше не буде.