我同意What's the best way to communicate between view controllers?给出的答案,但是如果我使用Interface Builder来设计我的应用程序视图呢?
不使用Application Delegate,如何从Controller对象中引用Model对象?
据我所知,我不能使用依赖注入的自定义Init方法将对模型的引用传递给IB。
请原谅我,因为我觉得我在这里缺少一些非常基本的东西。我查看了IB的Apple文档,但没有找到明确的答案。
答案 0 :(得分:3)
你的参考文章是一个很好的文章 - 就像你我喜欢将一个模型注入控制器(Smalltalk时代的旧习惯 - 特别是Dolphin Smalltalk非常广泛地遵循这种模式)。
我发现我的大多数控制器都有如下的init方法:
- (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];
请注意,我在init方法中嵌入了我的Nib文件的名称(如果你需要更多的灵活性,你可以创建另一个参数 - 但我还没有发现我的任何控制器都需要通用。这很有趣 - 就像在Dolphin中一样,控制器(和它们的视图)可以是非常合成的 - 通常在你的init方法中,你会从你的模型中挑选出子模型并为你的子组件调用init。我认为这可能是在iPhone上IB但我还没有探讨过这个想法。
然而你需要做一些额外的工作才能将模型传递给第一个控制器(这是我最初没想到的)。
编辑“YourAppDelegate.m”并将applicationDidFinishLaunching:方法更改为以下内容:
viewController = [[AppRootViewController alloc] initWithModel:[application model]]; viewController.view.frame = [[UIScreen mainScreen] applicationFrame];
[window addSubview:viewController.view];
[window makeKeyAndVisible];
如果您想使用其他项目类型,以下说明似乎也有效,但需要付出更多努力(我简化为上述内容):
编辑您的main.m文件并更改UIApplicationMain行(将最后一个参数替换为现有应用代理的名称) - 例如:
int retVal = UIApplicationMain(argc,argv,nil,@“YourAppDelegate”);
编辑“YourAppDelegate.m”并将applicationDidFinishLaunching:方法更改为以下内容:
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
viewController = [[AppRootViewController alloc] initWithModel:[application model]]; viewController.view.frame = [[UIScreen mainScreen] applicationFrame];
[window addSubview:viewController.view];
[window makeKeyAndVisible];
我在UIApplication中添加了一个类别方法:
- (MyModel *)model;
然后,您可以从应用程序中获取模型(如上所示)以及应用程序中的其他位置,例如
。viewModel = [[UIApplication sharedApplication] model];
虽然如果你像我所描述的那样总是将它传递给你的视图控制器,这可能是代码味道。
答案 1 :(得分:1)
InterfaceBuilder表示MVC模式中的V.因此,您不会使用您在IB中创建的任何操作来操纵模型。您将在IB创建的笔尖和模型之间使用某种委托。该委托在MVC中代理C,并且可以与用户界面以及底层模型进行通信。
答案 2 :(得分:0)
通常你不会直接在IB中触摸模型。您可以使用控制器连接视图,也可以将控制器的某些属性绑定到视图。然后编写代码(在控制器中)来访问模型。如果愿意,可以使用awakeFromNib方法,但也可以在控制器中实现自定义init。