Подтвердить что ты не робот

IOS Storyboards/NIBs низкоуровневая анатомия. Как они реализованы?

Меня заинтересовали детали низкого уровня механизмов NIB/Storyboards в iOS. Я хочу узнать больше об их внедрении - я заинтересован в разработке своего собственного механизма. Я нашел информацию о файлах NIB на сайте Apple.

Они сказали: a nib file describes these objects exactly as they were configured in Xcode. At runtime, these descriptions are used to recreate the objects and their configuration inside your application.. ОК. Но я не мог найти никакой информации о том, как реализованы раскадровки. Разве раскадровка - это всего лишь куча файлов NIB - по одному для каждого UIViewController? Или он использует другой механизм?

А как насчет источника XML NIBs/Storyboards? Есть ли переводчик underhood из XML в Objective-C исходный код? Детали низкого уровня будут оценены.

4b9b3361

Ответ 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:)

Установите символическую точку останова и посмотрите на сборку и переданные параметры.


Очень похожий процесс происходит при использовании восстановления состояния. Разница заключается в том, что представления предоставляются кодером и кодируют их свойства для этого кодера; во время восстановления просмотры восстанавливаются из реставратора состояния.

Ответ 2

На очень высоком уровне (чтобы замаскировать тонну деталей реализации) Xcode сериализует созданный вами графический объект (иерархию представлений и т.д.) с использованием механизма сохранения нативного объекта Cocoa, известного как NSCoding.

NSCoding - это протокол, который позволяет любому графику объектов, которые ему соответствуют, сериализоваться и сохраняться на диске или передаваться по сети, а затем восстанавливаться обратно в исходный граф объектов.

Конечно, вещи, такие как выходы и действия, также должны быть сохранены, так что там немного больше, чем просто объекты верхнего уровня и куча представлений, но вы можете думать о xib файле как о сериализации XML иерархию представления, которую вы создаете в Xcode.