Описание initWithNibName, awakeFromNib и viewDidLoad? - PullRequest
19 голосов
/ 06 августа 2009

Есть ли хороший обзор initWithNibName, awakeFromNib и viewDidLoad, в котором излагается наилучший способ использования каждого из них и точно описывается, что каждый из них делает? Я нахожу это очень запутанным. В шаблоне, сгенерированном с помощью View Controller, комментарий о initWithNibName говорит:

Назначенный инициализатор. Переопределите, чтобы выполнить настройку, которая требуется перед загрузкой представления.

За исключением того, что этот метод никогда не вызывается (я использую IB для настройки View Controller). Так я должен использовать awakeFromNib или viewDidLoad вместо инициализации?

Ответы [ 3 ]

35 голосов
/ 24 августа 2010

Я только что закончил некоторые исследования по этой теме, поэтому я решил поделиться некоторыми вещами, которые я узнал.

  1. Нет ничего плохого в использовании awakeFromNib с представлениями для iPhone. См. этот документ Apple Dev .

  2. initWithCoder - это , а не хорошее место для инициализации, когда представление загружается из файла NIB, поскольку другие элементы в том же файле NIB могут быть инициализированы или не инициализированы в этот момент. , Так, например, выход может быть нулевым. Все элементы в том же NIB-файле гарантированно будут правильно инициализированы при вызове awakeFromNib.

  3. viewDidLoad - это хорошее место для настройки в viewController.

Так почему же нужно использовать awakeFromNib в представлении? Одна из причин, по которой я могу придумать, состоит в том, что если у вас есть вещи, которые вы хотите сделать после того, как представление было инициализировано и подключено к другим объектам в файле NIB, но вы хотите инкапсулировать его только в представление. Это уменьшает связь с контроллером вида.

24 голосов
/ 06 августа 2009

Если вы создаете свои представления в IB, тогда вы должны использовать viewDidLoad. Это будет вызываться каждый раз при инициализации представления. Вы используете initWithNibName: когда вы создаете свое представление в коде. Вы не должны использовать awakeFromNib с представлениями для iPhone.

Причина, по которой initWithNibName, по-видимому, не вызывается, заключается в том, что построитель интерфейса фактически создает реальный экземпляр вашего контроллера представления, а затем сериализует это представление. Таким образом, когда вы создаете контроллер представления в IB (в основном добавляете его в свой проект), IB вызывает initWithNibName, но если вы не переопределили значение по умолчанию encodeWithCoder:, все переменные, которые вы установили там, будут ушел, когда представление загружено из пера (десериализовано). Как правило, это нормально, так как вы обычно хотите настроить свое представление на информацию, относящуюся к текущему, запущенному контексту ваших приложений, а не к предопределенным инициализаторам.

Даже если вы программно создаете представления и контроллеры представлений, вы все равно можете поместить всю инициализацию в viewDidLoad. Это часто лучше, потому что если ваше представление заканчивается кэшированием (выгружается) и затем возвращается на экран, viewDidLoad может быть вызван снова, тогда как ваш инициализатор не обязательно будет. Например, вы создаете представление программным способом и помещаете его в стек контроллера навигации - позже представление было закрыто и выдается предупреждение памяти, поэтому контроллер nav «выгружает» ваше представление, но не освобождает объект - когда представление возвращается (другие представления отключаются), контроллер nav снова вызовет viewDidLoad, так что вы можете повторно инициализировать, но initWithNib больше не будет вызываться. Обратите внимание, что это редкий случай, и в любом случае приложения большинства людей в этом случае будут ужасно умирать по другим причинам.

0 голосов
/ 13 августа 2014

viewDidLoad может вызываться более одного раза, поэтому он не подходит для большинства инициализаций (хотя на практике он вызывается только один раз, если вы не вмешиваетесь), поэтому awakeFromNib особенный и очень необходимый: он вызывается только один раз.

viewDidLoad не существует в UIView - UIView имеет awakeFromNib для инициализации, и нет других разумных опций.

В течение последних шести месяцев я с удовольствием использовал awakeFromNib с раскадровками (одной раскадровкой для приложения) вообще без каких-либо проблем, и он прекрасно работал со всеми розетками, настроенными в соответствии с документацией. Затем сегодня я разобрал некоторый код и вставил новый контроллер представления и представления, и ни один из них не работает, как я испытал в прошлом, то есть все выходы равны нулю в awakeFromNib. Моя теория проста - SDK отстой, потому что очень легко сделать что-то тривиальное где-то в вашей цепочке контроллеров / представлений и классов и сломать все.

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

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