10

我的视图控制器需要向几个模型对象发送消息。如何在视图控制器中获取对这些模型对象的引用?

这些模型对象是“单例”(因为系统中一次应该只有一个副本)并且它们被多个视图控制器使用。所以我不能在每个视图控制器的 init 方法中实例化它们。

我不能使用构造函数注入,因为运行时选择了用于创建视图控制器的 init 方法。

我不能使用“setter injection”,因为在任何时候(我知道)我都没有对新构造的视图控制器的引用和对“单例”模型对象的引用。

不想将模型对象变成正确的单例,并从视图控制器中调用它们的静态方法来检索单例实例,因为这是可测试性的问题。(将模型对象作为 AppDelegate 上的属性与执行此操作基本相同。)

我正在使用带有情节提要的 iOS 6。

4

4 回答 4

8

我刚刚处理了同样的问题。由于我使用的是故事板,所以我没有实例化我的UIViewControllers,所以我不能使用“构造函数注入”。我必须使用 setter 注入辞职。

我的应用程序根目录是UITabViewController. 假设它有两个UINavigationControllers,第一个是 a AControllerView,第二个是 s BControllerView。您可以通过AppDelegate.applicationDidFinishLaunchingWithOptions以下方式检索根控制器:

UITabBarController *tabBarController = (UITabBarController *) self.window.rootViewController;

然后你可以遍历控制器:

NSArray* viewControllers = [tabBarController viewControllers];
for (UIViewController *viewController in viewControllers) {
    UINavigationController *navigationController = (UINavigationController*) viewController;
    UIViewController *viewController = navigationController.topViewController;
    if ([viewController isKindOfClass: [AControllerView class]]) {
        AControllerView *a = (AControllerView*) viewController;
        // Inject your stuff
    }
    if ([viewController isKindOfClass: [BControllerView class]]) {
        BControllerView *b = (BControllerView*) viewController;
        // Inject your stuff
    }
}

希望能帮助到你。

于 2013-01-07T17:38:19.830 回答
4

为什么不使用NSNotificationCenter

NSNotificationCenter 对象(或简称为通知中心)提供了一种在程序中广播信息的机制。NSNotificationCenter 对象本质上是一个通知调度表。

您可以在单例或普通的两个中添加通知观察者,当您需要发送消息时,只需发布​​正确的通知即可。观察者将随后管理行动。

有关 NSNotificationCenter 的更多详细信息

于 2012-11-01T01:08:36.850 回答
2

这不是关于获取对视图控制器对象的引用吗?如果您使用的是故事板,那么使用的窗口rootViewController或 segues 将为您提供正确的视图控制器对象。

即:应用启动时视图控制器的实例是

self.window.rootViewController

当您在场景(视图控制器)之间进行转换时:

[segue destinationViewController]或者[segue sourceViewController]

如果您使用的是 xibs,您甚至可以使用界面构建器中的外部对象(代理对象)来提供模型对象。唯一的问题是您必须将笔尖实例化掌握在自己手中。

于 2013-03-28T12:17:49.433 回答
1

理想情况下,即使在使用情节提要时,第三方开发人员也将被允许使用他们自己的构造函数/初始化程序。

在此之前,您可以使用 setter/property 注入和中介模式,特别是因为您已经习惯了最佳实践和松散耦合。

我在这里写过它:http: //cocoapatterns.com/passing-data-between-view-controllers/

于 2014-09-12T15:18:57.300 回答