Описание initWithNibName, awakeFromNib и viewDidLoad?
Есть ли хороший обзор initWithNibName
, awakeFromNib
и viewDidLoad
, который позволяет наилучшим образом использовать каждый из них и точно описывает, что каждый делает? Я нахожу их очень запутанными. В шаблоне, сгенерированном с помощью контроллера просмотра, комментарий о initWithNibName
говорит:
Назначенный инициализатор. Переопределите для выполнения настройки, которая требуется перед загрузкой представления.
За исключением того, что этот метод никогда не называется (я использую IB для настройки контроллера просмотра). Так что я должен использовать awakeFromNib
или viewDidLoad
для инициализации вместо этого?
Ответы
Ответ 1
Если вы создаете свои представления в IB, вам следует использовать viewDidLoad
. Это будет вызываться каждый раз, когда представление инициализируется для установки. Вы используете initWithNibName
: при создании своего представления в коде. Вы не должны использовать awakeFromNib
с представлениями для iPhone.
Причина, по которой initWithNibName
, похоже, не вызывается, заключается в том, что конструктор интерфейса фактически создает реальный экземпляр вашего контроллера представлений и затем сериализует это представление. Таким образом, когда вы создаете контроллер представления в IB (в основном его добавьте в свой проект), IB вызывает initWithNibName
, но если вы не переопределили значение по умолчанию encodeWithCoder
:, любые измененные переменные, которые вы создали, будут ушел, когда представление загружено из наконечника (десериализован). Обычно это нормально, поскольку обычно вы хотите настроить свое представление с информацией, специфичной для ваших приложений, текущей, запущенной, а не предопределенными инициализаторами.
Однако, если вы программно создаете представления и контроллеры представлений, вы все равно можете поместить всю инициализацию в viewDidLoad
. Это часто бывает лучше, потому что, если ваше представление заканчивается тем, что оно кэшируется (выгружается), а затем возвращается на экран, viewDidLoad
можно вызвать снова, пока ваш инициализатор необязательно будет. Например, вы создаете представление программно и нажимаете его на стек контроллера навигатора - позднее представление закрывается и выдается предупреждение о сохранении памяти, поэтому навигационный контроллер "выгружает" ваше представление, но не освобождает объект - когда вид возвращается (другие виды удаляются), контроллер nav снова вызовет viewDidLoad
, чтобы вы могли повторно инициализировать, но initWithNib
больше не будет вызываться. Обратите внимание, что это редкий случай, и большинство приложений для людей будут умирать ужасно по другим причинам на этом этапе в любом случае.
Ответ 2
Я только что закончил некоторые исследования по этой теме, поэтому я решил поделиться некоторыми вещами, которые я узнал.
-
Нет ничего плохого в использовании awakeFromNib
с представлениями для iPhone. См. этот документ Apple Dev.
-
initWithCoder
не является хорошим местом для инициализации, когда представление загружается из файла NIB, потому что другие элементы в одном файле NIB могут быть или не быть инициализированы в этой точке. Например, выход может быть ноль. Все элементы в одном файле NIB гарантированно будут правильно инициализированы при вызове awakeFromNib
.
-
viewDidLoad
- хорошее место для работы с настройками в viewController.
Итак, почему вы хотите использовать awakeFromNib
в представлении? Одна из причин, о которой я могу думать, это то, что у вас есть вещи, которые вы хотите сделать после того, как представление было инициализировано и подключено к другим объектам в файле NIB, но вы хотите инкапсулировать его только в представлении. Это уменьшает связь с контроллером представления.
Ответ 3
viewDidLoad можно вызвать более одного раза, поэтому для большинства инициализации это не подходящее место (хотя на практике он называется только один раз, если вы не вмешиваетесь) - вот почему awakeFromNib является особенным и очень необходимым: он получает только один раз.
viewDidLoad не существует в UIView - UIView имеет awakeFromNib для инициализации, и нет других разумных параметров.
В течение последних шести месяцев я с удовольствием использовал awakeFromNib с раскадными версиями (один раскадровки для приложения) без каких-либо проблем, и он отлично себя ведет со всеми выходами, настроенными, как указано в документации. Затем сегодня я разделил код и установил новый контроллер и представления, и ни один из них не работает, как я уже имел в прошлом, т.е. Все выходы nil в awakeFromNib. Моя теория проста - SDK сосет, потому что очень легко сделать что-то тривиальное где-то в вашей цепочке контроллеров/представлений и классов и сломать все.
Теперь я собираюсь исследовать эту бессмысленную тему, но опять же, когда все, что мне нужно, - это простое последовательное место для инициализации.