Шаблон приложения iOS на основе представления - PullRequest
4 голосов
/ 15 ноября 2010

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

Я понимаю, что приложение получает имя основного файла пера (обычно MainWindow.xib) сформируйте файл * -Info.plist.Я не понимаю, как XCode узнает, какой файл пера связан с контроллером, который по умолчанию создается с этим шаблоном приложения на основе представления.В руководстве вы начнете с приложения на основе Windows, и вам «придется написать» что-то вроде:

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

[self setMyViewController:aViewController];

, что имеет смысл.Однако оказывается, что в шаблоне приложения iOS на основе View такого нет, и что эта спецификация пера на самом деле не была нужна, если вы создали свой подкласс UIViewController с опцией «С XIB для пользовательского интерфейса»."проверил.Мой вопрос: как XCode узнает, какой кончик связан с этим контроллером, то есть хранит ли он это соединение в некоторых файлах, или, возможно, по какому-то соглашению (возможно, с тем же именем для контроллера и файла кончика)?Кроме того, откуда этот субтитр «Загружен из« MyViewBasedAppController »» в представлении контроллера интерфейса Интерфейса в MainWindow.xib?Это определенно не там, когда я добавляю контроллер вручную, поэтому мне любопытно, что делает XCode за моей спиной, когда мне кажется, что я просто выбираю простой шаблон кода.

1 Ответ

6 голосов
/ 15 ноября 2010

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

Это будет 'MainWindow', свежее из шаблона.Если вы откроете MainWindow.xib, то увидите, что внутри есть объект с именем «[имя проекта] App Delegate», и если вы покажете инспектор и проверите на вкладке «i», вы увидите тип класса, которыйназван в верхней части.Если вы откроете вкладку соединений (стрелка вправо), то увидите, что у владельца файла (который сам является приложением UIA) связано свойство «делегата».

Вы также увидите, что он имеетрозетка под названием «viewController».Это прикреплено к другому объекту в xib под названием «[имя проекта] View Controller».Проверьте тип на этом, и вы увидите, что это тип контроллера представления, который Xcode добавил в ваш проект.Взглянув на его атрибуты (первая вкладка в инспекторе с графическим изображением слайдера), вы также увидите, что отдельный файл пера определен как содержащий его основные детали.

Ради аргумента предположим, что я вызвал мойпроект 'NibTest' и не вносил изменений.

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

Затем из 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.Даже спросите пользователя, если хотите (хотя это было бы очень плохой идеей по соображениям безопасности).

...