Выпуск IBOutlets в представлении UIViewControllerDidUnload? - PullRequest
7 голосов
/ 06 июля 2010

Я немного сбит с толку относительно того, что происходит именно в UIViewController s на основе Nib. При создании подкласса UIViewController шаблон содержит очень специфический комментарий в методе viewDidUnload:

// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;

К каким подпредставлениям это относится?

  • Те, которые я инициализировал в viewDidLoad? (Я бы сказал да)
  • Те, которые я инициализировал в initWithNibName? (Я бы сказал нет)
  • IBOutlets, которые ссылаются на объекты в Nib?

Если я использую контроллер вида следующим образом:

MyViewController *controller = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];
[self.navigationController pushViewController:controller animated:YES];
[controller release];

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

Но предположим, что я использовал MyViewController в качестве переменной экземпляра, которую можно нажимать несколько раз:

if(self.myViewController == nil) {
    self.myViewController = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];
}
//Change some state which should be reflected in the view
self.myViewController.someProperty = someValue;
[self.navigationController pushViewController:self.myViewController animated:YES];

Что происходит в MyViewController, если я выпускаю IBOutlet в viewDidUnload? Могу ли я рассчитывать на получение новой ссылки на него в следующий viewDidLoad?

Другими словами: что происходит с самим видом после viewDidUnload? Выпускается ли он и перезагружается ли из Nib, если контроллер снова нажимается? Или вид остается в памяти? И если да, перезапускаются ли розетки до viewDidLoad?

Если или представление остается в памяти, а выходы переустанавливаются до viewDidLoad или перезагружаются при каждом нажатии контроллера, я полагаю, было бы правильным сбросить выходы в viewDidUnload (даже если в первый случай это не важно). Но в противном случае (в частности, если представление остается в памяти и выходы НЕ переустанавливаются), освобождение подпредставлений в viewDidUnload неправильно для представленного мной варианта использования, я прав?

1 Ответ

7 голосов
/ 06 июля 2010

Из документации UIViewController , раздел Управление памятью:

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

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

И да, вы можете рассчитывать на то, что ваши розетки будут указывать на действительные объекты, когдаviewDidLoad называется.Снова из документации UIViewController, на viewDidLoad:

Этот метод вызывается после того, как контроллер представления загрузил свои связанные представления в память.

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