Вопрос

Я прочитал руководство Apple «Ваше первое приложение для iOS», и все, что мне кажется кристально ясным для меня. Однако, когда я пытаюсь понять, как работает шаблон приложения для iOS, основанный на просмотре, я сталкиваюсь с некоторыми интересными загадками.

Я понимаю, что приложение получает основное имя файла NIB (обычно, mainwindow.xib) образует файл *-info.plist. Чего я не понимаю, так это то, как XCODE узнает, какой файл NIB связан с контроллером, который создается с помощью этого шаблона приложения, основанного на представлениях по умолчанию. В руководстве вы начинаете с приложения на основе окон, и вам нужно написать «что-то вроде:

MyViewController *aViewController = [[MyViewController alloc]
initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]];

[self setMyViewController:aViewController];

что имеет смысл. Тем не менее, выясняется, что в шаблоне приложения на основе просмотра такого нет, и что эта спецификация NIB на самом деле не была на самом деле необходима в первую очередь, если вы создали свой подкласс UiviewController с опцией «с XIB для пользовательского интерфейса "Проверено. Мой вопрос: как XCODE узнает, какой NIB связан с этим контроллером, то есть он хранит это соединение в некоторых файлах или, возможно, каким -то соглашением (возможно, то же имя для контроллера и файла NIB)? Более того, откуда это «загружено из подзаголовника» в «MyViewBasedAppController» из «MyViewBasedAppController», проведенного в представлении интерфейсного строителя на контроллере в Mainwindow.xib? Это определенно не там, когда я добавляю контроллер вручную, поэтому мне любопытно, что магия делает Xcode за моей спиной, когда я думаю, что я просто выбираю простой шаблон кода.

Это было полезно?

Решение

Если вы посмотрите в целевой информации (дважды щелкните цель, чтобы поднять это), вкладка «Свойства», вы увидите имя основного файла NIB. Слова «nib» и «xib» взаимозаменяемы для этих целей; XIB - это просто более новая альтернатива для NIB.

Это будет «Mainwindow» только из шаблона. Если вы откроете Mainwindow.xib, вы увидите, что есть объект с именем «Degate» [Имя проекта], и если вы покажете инспектора и проверьте на вкладке «Я», вы увидите тип класса, который Назван наверху. Если вы проверите вкладку «Соединения» (стрелка с правой стороной), вы увидите, что владелец файла (который является самой UIApplication) имеет свое свойство «делегата».

Вы также увидите, что у него есть розетка под названием «ViewController». Это подключено к другому объекту в XIB, называемом «контроллер представления проекта». Проверьте тип на этом, и вы увидите, что это тот тип контроллера представления, который XCode добавил к вашему проекту. Глядя на его атрибуты (первая вкладка в Инспекторе, с графикой слайдера), вы также увидите, что отдельный файл NIB определяется как содержащий его основные детали.

Ради аргумента, предположим, что я назвал свой проект «Nibtest» и не внес никаких изменений.

Во время выполнения устройство загружает info.plist. Там видит, что делегат имеет тип Nibtestappdelegate. Таким образом, это создаст экземпляр экземпляра класса Nibtestappdelegate и установит на него свойство делегата UIAPLICATION.

Затем из Mainwindow.nib будет увидеть, что у Nibtestappdelegate есть участник с именем ViewController типа NibtestViewController. Таким образом, это создаст экземпляр этого и установит свойство ViewController на экземпляре NibtestAppDelegate, который он только что создал для него.

Делая это, это откроет другой XIB и продолжит делать те же шаги.

Objective-C имеет полностью рефлексивную среду выполнения, поэтому вы можете создавать создание объектов по имени класса во время выполнения. Это одно из различий между Objective-C и C ++, например.

Xcode не генерирует какого -либо скрытого кода и не полагается на какие -либо скрытые соглашения об именах. Все это выясняется во время выполнения ОС.

Изменить: например, вместо вашего примера:

    MyViewController *aViewController = [[MyViewController alloc]
initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]];

Вы могли бы сделать:

    MyViewController *aViewController = [[NSClassFromString(@"MyViewController") alloc]
initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]];

Они будут работать одинаково, пока MyViewController существует в программе или в более широком времени выполнения.

Вы можете альтернативно передать любой другой строковый объект, который вам нравится NSClassFromString. Анкет Даже спросите пользователя об этом, если хотите (хотя это было бы действительно плохой идеей по соображениям безопасности).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top