如何将依赖项注入iOS视图控制器?

时间:2012-11-01 00:35:52

标签: objective-c ios ios6 inversion-of-control

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

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

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

我不能在任何时候使用“setter injection”(我知道)我是否同时引用了新构造的视图控制器和对“singleton”模型对象的引用。

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

我正在使用iOS 6和Storyboard。

4 个答案:

答案 0 :(得分:8)

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

我的应用根是UITabViewController。假设它有两个UINavigationController s,第一个为AControllerView,第二个为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
    }
}

希望它有所帮助。

答案 1 :(得分:4)

为什么不使用NSNotificationCenter

  

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

您可以在单身或普通的情况下添加通知观察者,当您需要发送消息时,只需发布​​正确的通知即可。然后观察者将管理行动。

More detail on NSNotificationCenter

答案 2 :(得分:2)

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

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

self.window.rootViewController

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

[segue destinationViewController][segue sourceViewController]

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

答案 3 :(得分:1)

理想情况下,即使使用故事板,第三方开发者也可以使用自己的构造函数/初始化程序。

在那之前你可以使用setter / property注入和mediator模式,特别是因为你习惯了最佳实践和松散耦合。

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