2010-11-14 3 views
4

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

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

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

[self setMyViewController:aViewController]; 

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

ответ

6

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

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

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

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

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

После этого вы увидите из MainWindow.nib, что NibTestAppDelegate имеет член с именем viewController типа NibTestViewController. Поэтому он создаст экземпляр этого объекта и установит свойство viewController в экземпляре NibTestAppDelegate, который он только что создал.

При этом он откроет другой xib и продолжит выполнение тех же шагов.

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

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

EDIT: например, вместо вашего примера:

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

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

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

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

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

+0

Отличное объяснение всего процесса, большие пальцы. –

+0

Ну, вы совершенно правы в создании классов от их имени, но это не совсем то, что я спросил. Что вы здесь говорите: «При этом он откроет другой xib и продолжит делать то же самое». похоже, не отвечает на мой вопрос: как разрешено, что файл nib для контроллера NibTestViewController был тем самым файлом NibTestViewController.xib? Иными словами, как известно, что в этом случае должен быть любой файл nib для загрузки (так как мы могли бы четко создать контроллер без файла nib)? – itim

+0

«... Посмотрев на его атрибуты (первая вкладка в инспекторе с графикой ползунка), вы также увидите, что отдельный файл nib указан как содержащий его основные данные» - извините, я действительно устал, когда прочитав это. Этот ответ на самом деле прибивает его, большое спасибо! – itim

Смежные вопросы