Ответ 1
Файлы раскадровки и XIB скомпилированы в файлы NIB в двоичном формате. Эти файлы можно найти в комплекте при развертывании приложения.
Файлы NIB проще понять. Они содержат массив иерархий объектов. Раскадровки сложнее, поскольку они содержат целую сцену, поэтому в нее добавлено больше метаданных (например, какой контроллер представления является начальным в сцене и т.д.). Segues также являются декодируемыми объектами.
Каждый объект, определенный в файлах NIB и раскадровки, имеет уникальный ключ (например, vXZ-lx-hvc
, который при компиляции имеет имя присоединенного к нему класса, поэтому он, наконец, LNViewController-vXZ-lx-hvc
).
При попытке загрузить объекты, определенные в NIB или раскадровке (обычно это просмотр, просмотр контроллеров и segues, а также другие объекты, которые вы можете определить в Interface Builder), декодер типа UINibDecoder
, который отвечает за чтение данных в двоичном файле NIB и декодирование его в живые объекты. Затем выделяется объект и вызывается initWithCoder:
, передавая декодер. Затем объект вызывает различные методы декодирования для каждого поддерживаемого свойства. Например, представление таблицы будет расшифровывать, в частности, его стиль, его фоновый вид, высоту его ячейки, его делегат и т.д. После завершения декодирования загрузчик NIB вызывает awakeFromNib
, чтобы уведомить объект, который он был загружен из NIB.
Кадры разбиваются на несколько файлов NIB, обычно это файл NIB для каждого контроллера представления. Когда объекты загружаются из раскадровки, внутри UIStoryboard
есть метаданные, для которых NIB файл загружается для конкретного контроллера вида. Когда контроллер представления декодируется (в пределах его initWithCoder:
он загружает всю свою иерархию представлений, значения свойств, прикрепленные объекты и т.д.
Наконец, каждый файл NIB (и, в дополнение, раскадровки) способен включать информацию о значении ключа, которая применяется после успешного декодирования объекта.
Чтобы реализовать подобную систему, вам необходимо предоставить аналогичную систему, которая может вывести тип, выделить объект и затем инициализировать его собственным декодером. Поскольку представления и контроллеры представлений реализуют протокол NSCoding
, вы можете легко исследовать, какие ключи они поддерживают, и создать ваш декодер и формат данных для поддержки тех же ключей.
Если вы хотите следовать потокам загрузки NIB и раскадровки, я предлагаю посмотреть дампы классов, установить контрольные точки для ключевых методов и проверить переданные параметры на вызовы методов. При отладке на 64-битном симуляторе вывод сборок очень легко читается, и вы легко можете легко проверить переданные параметры, используя po $arg1
для объекта self
, po NSStringFromSelector($arg2)
для вызываемого метода selector, po $arg3
. для следующих параметров.
Предлагаемые методы для начала:
-[UIStoryboard instantiateViewControllerWithIdentifier:]
-[UIStoryboard instantiateInitialViewController]
-[UIStoryboard nibForViewControllerWithIdentifier:]
-[UINibDecoder decodeObjectForKey:]
(и другие методы -decode***ForKey:
)
Установите символическую точку останова и посмотрите на сборку и переданные параметры.
Очень похожий процесс происходит при использовании восстановления состояния. Разница заключается в том, что представления предоставляются кодером и кодируют их свойства для этого кодера; во время восстановления просмотры восстанавливаются из реставратора состояния.