我同意在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];


尽管如果您像我之前描述的那样始终将其传递给视图控制器,则可能是代码的味道。

10-08 07:28
查看更多