2009-06-10 3 views
3

Я согласен с ответами, указанными в What's the best way to communicate between view controllers?, но что, если я использую интерфейс Builder для разработки своего приложения Views?Как поместить «M» в MVC с помощью Interface Builder

Без использования делегата приложения, как я могу ссылаться на объекты модели из объектов контроллера?

Насколько я могу судить, я не могу поставить пользовательские методы Init, которые используют инъекцию зависимости, чтобы передать ссылки на модель в IB.

Простите меня, поскольку я чувствую, что мне не хватает чего-то очень элементарного здесь. Я просмотрел документацию Apple для IB, но не нашел четкого ответа.

+0

Как добавить делегат между контроллерами XIB и объектами модели? Как я могу получить ссылку на экземпляр объекта контроллера? –

ответ

3

В статье ваша рекомендация хорошая - как и вы. Мне нравится вводить модель в контроллер (старая привычка от Smalltalk дней - в частности, Dolphin Smalltalk следует этому шаблону довольно широко).

Я обнаружил, что большинство моих контролеров инициализации методы, такие как следующие:

- (id)initWithItem:(id<Nameable>)item addingTo: (id<ModelContainer>)model { 
    if (self = [self initWithNibName:@"ItemEditTableToolbarView" bundle:nil]) { 
     self.namedItem = item; 
     self.container = model; 
    } 

    return self; 
} 

Вы можете назвать ваш контроллер, как это:

ReDoListEditController *itemViewController = [[ReDoListEditController alloc] initWithItem: item addingTo: model]; 
    [self.navigationController pushViewController: itemViewController animated: YES]; 
    [itemViewController release]; 

Обратите внимание, что я вставлять имя моего Nib-файл в методе init (вы можете сделать этот другой параметр, если вам нужна большая гибкость, но я еще не нашел, что какой-либо из моих контроллеров должен быть общим. Это интересно - как в Dolphin, контроллеры (и их представления) могут быть очень композиционным - так часто в вашем методе init, yo u выберет подмодели из вашей модели и вызовет init для ваших подкомпонентов. Я думаю, что это возможно на iPhone с IB, но я еще не изучил эту идею.

Однако вам нужно сделать немного дополнительной работы, чтобы передать вашу модель первому контроллеру (это было то, что я изначально не выяснил).

  1. Создать приложение оконного Based в XCode (если вы хотите приложение на основе навигации, вы можете добавить это с кодом довольно легко)
  2. Edit «YourAppDelegate.m» и изменить applicationDidFinishLaunching: метод чем-то вроде следующий:

    viewController = [[AppRootViewController alloc] initWithModel: [модель приложения]]; viewController.view.frame = [[UIScreen mainScreen] applicationFrame];

    [window addSubview: viewController.Посмотреть];

    [window makeKeyAndVisible];

Если вы хотите использовать другой тип проекта, следующие инструкции также, кажется, работает, но его намного больше усилий (я упростил к вышесказанному):

  1. Удалить файл MainWindow.xib (звучит радикальным, но вы хотите создать MainWindow себя - вы можете создать все другие представления с IB)
  2. Редактировать свой .plist файл и удалите запись MainWindow.xib (его обычно последний пункт)
  3. Редактировать файл main.m и изменить UIApplicationMain строку (заменив последний параметр с именем существующего приложения делегата) - например .:

    INT RetVal = UIApplicationMain (ARGC, ARGV, ноль, @ "YourAppDelegate");

  4. Edit "YourAppDelegate.m" и изменить applicationDidFinishLaunching: метод что-то вроде следующего:

    окна = [[UIWindow Alloc] initWithFrame: [[UIScreen В начале] граница]];

    viewController = [[AppRootViewController alloc] initWithModel: [модель приложения]]; viewController.view.frame = [[UIScreen mainScreen] applicationFrame];

    [window addSubview: viewController.view];

    [window makeKeyAndVisible];

Я добавил метод категории для UIApplication называется:

- (MyModel *)model; 

Вы можете получить модель из приложения (как я показываю выше), а также в других местах в вашем приложении, например,

viewModel = [[UIApplication sharedApplication] model]; 

Хотя, если вы всегда передаете его в свой контроллер, как я описал, это, вероятно, запах кода.

+1

Спасибо Тим. Это лучший ответ, но, как вы сказали, не на 100% потрясающий! Сообщение похоже, что серьезные разработчики не используют IB - неужели это не так? –

+0

У меня есть догадка, что есть способ сделать некоторый первоначальный запуск в коде, чтобы вы могли запустить этот первый контроллер с кодом. У меня есть несколько образцов, чтобы попробовать и отчитаться. – TimM

+0

Серьезные разработчики определенно используют IB. Как уже было сказано, это просто проблема с контроллером корневого представления приложения, а не со всеми контроллерами представлений. Вы все равно можете выложить все, что управляется каждым отдельным контроллером представления в IB, просто отлично. –

0

Обычно вы не трогаете модель непосредственно в IB. Вы подключаете свои представления к своим контроллерам, возможно, привязываете некоторые свойства контроллеров к представлениям. Затем вы пишете код (в контроллерах) для доступа к модели. Вы можете использовать метод awakeFromNib, если хотите, но вы также можете реализовать пользовательский init в контроллере.

1

ИнтерфейсBuilder представляет V в шаблоне MVC. По этой причине вы не будете использовать ничего, что вы создали бы в IB, чтобы манипулировать вашими моделями. Вы будете использовать какой-то делегат между созданным IB модулем и моделями. Этот делегат представляет C в MVC и может разговаривать как с пользовательским интерфейсом, так и с базовой моделью.

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