我同意在What's the best way to communicate between view controllers?处给出的答案,但是如果我使用Interface Builder设计应用程序视图怎么办?
不使用应用程序委托,如何在Controller对象中引用Model对象?
据我所知,我无法放置使用依赖注入的自定义Init方法来将对模型的引用传递给IB。
原谅我,因为我觉得这里缺少一些基本知识。我查看了IB的Apple文档,但没有找到明确的答案。
最佳答案
您所参考的文章是不错的文章-就像您一样,我喜欢将模型注入控制器(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];
请注意,我将Nib文件的名称嵌入init方法中(如果需要更大的灵活性,可以输入另一个参数-但我还没有发现我的任何控制器都需要通用。这很有趣-就像在Dolphin中一样,控制器(及其视图)的组成可能非常复杂-因此通常在您的init方法中,您会从模型中选择子模型并为子组件调用init。我认为这可能在具有IB的iPhone上可行,但我尚未探讨过这个想法。
但是,您需要做一些额外的工作才能将模型传递给第一个控制器(这是我最初没有想到的)。
在XCode中创建一个基于窗口的应用程序(如果您想要基于导航的应用程序,则可以很容易地用代码添加它)
编辑“ YourAppDelegate.m”,并将applicationDidFinishLaunching:方法更改为如下所示:
viewController = [[AppRootViewController alloc] initWithModel:[应用程序模型]];
viewController.view.frame = [[UIScreen mainScreen] applicationFrame];
[window addSubview:viewController.view];
[window makeKeyAndVisible];
如果您想使用其他项目类型,以下说明似乎也可以工作,但是需要付出更多的努力(我已简化为上述内容):
删除MainWindow.xib文件(听起来很激进,但您想自己创建MainWindow-您仍然可以使用IB创建所有其他视图)
编辑您的.plist文件并删除MainWindow.xib条目(通常是最后一项)
编辑您的main.m文件并更改UIApplicationMain行(将最后一个参数替换为现有应用程序委托的名称)-例如:
int retVal = UIApplicationMain(argc,argv,nil,@“ YourAppDelegate”);
编辑“ YourAppDelegate.m”,并将applicationDidFinishLaunching:方法更改为如下所示:
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
viewController = [[AppRootViewController alloc] initWithModel:[应用程序模型]];
viewController.view.frame = [[UIScreen mainScreen] applicationFrame];
[window addSubview:viewController.view];
[window makeKeyAndVisible];
我在UIApplication中添加了一个类别方法,名为:
- (MyModel *)model;
然后,您可以从应用程序中获取模型(如上图所示),也可以从应用程序中的其他位置获取模型。
viewModel = [[UIApplication sharedApplication] model];
尽管如果您像我之前描述的那样始终将其传递给视图控制器,则可能是代码的味道。