Ответ 1
Короткий ответ
Контроллер вашего представления и его иерархия представлений загружаются из отдельных файлов nib во время выполнения.
Сначала загружается ваш контроллер просмотра и получает awakeFromNib
, когда загружается его nib, но его иерархия иерархии представления еще не загружена, поэтому в awakeFromNib
вы не должны предполагать, что любые выходы в иерархию представлений были установить еще.
Контроллер вашего представления получает viewDidLoad
после того, как его иерархия иерархии представлений загружена, поэтому в viewDidLoad
вы можете предположить, что все розетки установлены.
Длинный ответ
Когда Xcode создает ваше приложение, оно компилирует раскадровку. Результатом является пакет (папка, которую Finder рассматривает как файл), содержащий Info.plist
и набор файлов .nib
. Пример из одного из моих проектов:
:; pwd
/Users/mayoff/Library/<snip>/Pinner.app/Base.lproj/Main.storyboardc
:; ll
total 80
drwxr-xr-x 10 mayoff staff 340 May 11 22:13 ./
drwxr-xr-x 4 mayoff staff 136 May 11 22:13 ../
-rw-r--r-- 1 mayoff staff 1700 May 11 22:13 AccountCollection.nib
-rw-r--r-- 1 mayoff staff 1110 May 11 22:13 AccountEditor.nib
-rw-r--r-- 1 mayoff staff 2999 May 11 22:13 BYZ-38-t0r-view-8bC-Xf-vdC.nib
-rw-r--r-- 1 mayoff staff 439 May 11 22:13 Info.plist
-rw-r--r-- 1 mayoff staff 7621 May 11 22:13 LqH-9K-CeF-view-OwT-Ts-HoG.nib
-rw-r--r-- 1 mayoff staff 6570 May 11 22:13 OZq-QF-pn5-view-xSR-gK-reL.nib
-rw-r--r-- 1 mayoff staff 2473 May 11 22:13 UINavigationController-ZKB-z3-xgf.nib
-rw-r--r-- 1 mayoff staff 847 May 11 22:13 UIPageViewController-ufv-JN-y6U.nib
Info.plist
сопоставляет имена сцен в вашем раскадровке с соответствующими перьями:
:; plutil -p Info.plist
{
"UIViewControllerIdentifiersToNibNames" => {
"AccountCollection" => "AccountCollection"
"UINavigationController-ZKB-z3-xgf" => "UINavigationController-ZKB-z3-xgf"
"UIPageViewController-ufv-JN-y6U" => "UIPageViewController-ufv-JN-y6U"
"AccountEditor" => "AccountEditor"
}
"UIStoryboardDesignatedEntryPointIdentifier" => "UINavigationController-ZKB-z3-xgf"
"UIStoryboardVersion" => 1
}
Сцена появляется только в этом списке, если у него есть идентификатор раскадровки, или к нему подключается segue, или это начальная сцена.
Список файлов nib в Info.plist
do not содержит иерархии представлений этих контроллеров представлений. Каждый из этих файлов nib содержит контроллер представления его сцены и любые другие объекты верхнего уровня в сцене, но не вид контроллера представления или любые его подзоны.
Отдельный файл nib содержит иерархию представлений для сцены. Имя иерархии вида nib, полученное из идентификаторов объектов контроллера вида и его верхнего уровня. Вы можете увидеть идентификатор объекта любого объекта в раскадровке в "Identity Inspector" в Xcode. Например, мой идентификатор ID сцены сценария "AccountCollection" равен BYZ-38-t0r
, а его идентификатор вида 8bC-Xf-vdC
, поэтому иерархия представления для сцены находится в файле BYZ-38-t0r-view-8bC-Xf-vdC.nib
. Файл nib файла сцены содержит имя файла nib файла иерархии представлений:
:; strings - AccountCollection.nib |grep -e '-.*-'
UIPageViewController-ufv-JN-y6U
BYZ-38-t0r-view-8bC-Xf-vdC <---------
UpstreamPlaceholder-5Hn-fK-fqQ
UpstreamPlaceholder-8GL-mk-Rao
q1g-aL-SLo.title
Если сцена не имеет иерархии представлений, тогда будет только файл nib для контроллера представления и отдельный файл nib для иерархии представлений. Например, сценарий UIPageViewController
не имеет иерархии представлений в раскадровке, поэтому нет иерархии представлений nib, соответствующей UIPageViewController-ufv-JN-y6U.nib
.
Итак, что же все это связано с вашим вопросом? Вот что: когда ваше приложение загружает сцену из "раскадровки", она загружает файл nib, содержащий контроллер представления (и другие вершины -уровневые объекты). Когда загрузчик nib загружает этот файл nib, он отправляет awakeFromNib
всем объектам, которые он только что загрузил. Это включает в себя ваш контроллер представления, но он не включает ваши представления, потому что ваши представления не были в этом файле nib.
Позже, когда вашему контроллеру просмотра будет предложено его свойство view
, он загружает файл nib, содержащий его иерархию представлений. Контроллер представления передает себя в -[UINib instantiateWithOwner:options:]
как аргумент owner
. Так загрузчик nib может подключать объекты в иерархии представлений к выходам и действиям контроллера вида.
Когда загрузочный загрузчик nib загружает иерархию представлений, он отправляет awakeFromNib
ко всем объектам, которые он только что загрузил. Поскольку ваш контроллер просмотра был не одним из этих объектов, ваш контроллер представления не получает сообщение awakeFromNib
в настоящее время.
Когда возвращается instantiateWithOwner:options:
, контроллер представления отправляет сообщение viewDidLoad
. Это ваша возможность внести изменения в иерархию представлений.