2011-03-03 21 views
1

我有一个简单的iOS应用程序,在UINavigationController下有一个UIViewController。 UIViewController有一个NSManagedObjectContext的IBOutlet。如何通过Interface Builder的XIBs传递NSManagedObjectContext

AppDelegate具有用于导航控制器的IBOutlet - 但不是视图控制器。视图控制器会自动实例化XIB进程(作为导航控制器的子项)。

使用此设置,如何干净地将应用程序委托的NSManagedObjectContext分配或传递给视图控制器的IBOutlet属性。有一个导航控制器的方式:)和应用程序委托没有UIViewController的直接属性。

这是一个奇怪的问题,我想将一个属性从一个XIB组件链接到另一个组件的属性。我所做的大部分XIB工作都需要一个属性,然后将它指向XIB中的一个对象,然后将其实例化为正常流程,但在这种情况下,上下文在应用程序委托中正确创建,我只想在实例化时将其传递给视图控制器。

+0

我认为还值得考虑一个具有9个视图控制器的应用程序 - 在不同时间使用 - 所有这些都需要访问托管上下文。在某些情况下,view-A和view-C需要上下文,但是view-B不需要。简单地将它传递给每个视图控制器的幼稚方法似乎很麻烦。这是否意味着view-A使用上下文创建view-B(即使view-B不需要它),以便view-B可以创建view-C并将它传递给它?我发现这使得我的愚蠢的视图控制器太聪明,应用程序不灵活。 – 2011-03-03 19:58:47

回答

0

你并不需要通过它,只是从应用程序的委托抓住它要求:

#import "MyAppDleegate.h" 

NSManagedObjectContext* moc = [(MyAppDelegate*)[UIApplication sharedApplication].delegate managedObjectContext]; 
+0

这是一种方法(实际上是一种非常实用的方法),但在某种程度上,它将上下文硬编码为视图本身。我喜欢它颠倒设置,但作为一个单例,它违反了“依赖注入”的原则。例如,单元测试这个特定的视图控制器是很困难的,因为它会继续向UIApplication和AppDelegate提供它所需要的资源。理想的解决方案是在运行时将视图“提供”给视图控制器,诀窍在于将它连接到ala IB。 – 2011-03-03 20:06:27

+0

True - 在有多个线程访问托管对象的某些应用程序中,我使用了NSManagedObjectContext上的一个类别,它根据需要创建moc,使用线程名称作为标识符 - 然后将它们存储在字典中,线程名称为key 。显然你必须命名所有线程,并断言你是否从一个未命名的线程获得请求。这是关于使用IB的最后一件事情,我喜欢XCode 4现在建立连接的方式,但是不得不发现像传递一个moc这样的技巧是非常令人愤怒的。 – 2011-03-03 23:45:35

0

苹果的文档建议您传递给你的管理对象范围内引用类的要求他们,而不是引用它从您的应用程序委托。

这是application:didFinishLaunchingWithOptions:在我的一个Core Data项目中的样子。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{   
    LocationsViewController *lvc = (LocationsViewController *)self.navigationController.topViewController; 
    lvc.managedObjectContext = self.managedObjectContext; 
    assert(lvc.managedObjectContext != nil); 
    [self.window addSubview:self.navigationController.view]; 
    [self.window makeKeyAndVisible]; 

    return YES; 
} 

你会看到我也从一个带有单个根视图控制器的UINavigationController开始。

+0

谢谢马克。不幸的是,我没有参考我的应用程序委托中的主视图控制器 - 只是导航控制器。 – 2011-03-03 19:53:53

+0

但是,您已将Interface Builder中的主视图控制器设置为导航控制器的根视图控制器。只要让导航控制器返回它的顶视图控制器。在您的视图控制器上为NSManagedObjectContext设置一个公共属性。使用AppDelegate中的'self.managedObjectContext'在视图控制器上设置'managedObjectContext'属性。 – 2011-03-03 20:49:54

+0

是的,我可以做到这一点 - 但正在寻找一种方法在Interface Builder的XIB中完成它。我有9个其他视图控制器不在导航堆栈上,也需要托管的对象上下文,我也想将它应用于这些。 – 2011-03-03 21:06:16

0

你有正确的想法,但你摔跤的问题似乎完全是你自己的创作。你说你的应用程序委托有一个导航控制器的出口,但不是导航控制器的根视图控制器,因为你已经设置了你的笔尖,以便在加载笔尖时创建视图控制器。这没什么不妥,但也没有理由说应用程序代表不应该为该控制器设置插座。事实上,网点的全部理由是要获得从笔尖加载的东西的参考。

为您的根视图控制器的应用程序委托添加一个插座,并将其连接。然后,应用程序委托可以为控制器提供对托管对象上下文的引用。

关于您关于多个视图控制器的问题,我想知道什么样的真实世界的应用程序可能具有需要数据的视图控制器(A),加载不需要任何数据的另一个视图控制器(B)然后是第三个(C),这又需要数据?一个现实的例子可能会有所帮助,如果有的话。

请记住,您不必将整个托管对象上下文传递给每个连续的视图控制器。您可以通过传递托管对象来传递控制器需要完成工作的模型部分。

相关问题