如何在内部UINavigationControllers中使用UITabBarController时共享ManagedObjectContext

时间:2010-11-04 18:26:06

标签: iphone ipad core-data uitabbarcontroller nsmanagedobjectcontext

我有一个架构问题。我的应用程序在应用程序窗口中使用TabBarController。 ApplicationDelegate创建了managedObjectContext,虽然它实际上不需要它。

TabBarController中的每个ViewController都是一个NavigationViewController。每个NavigationController的第一个视图控制器是我的自定义视图。所有都是通过Interface Builder创建链接。

现在,如何以正确的方式传递managedObjectContext?实际上我需要我的视图尽快加载数据,以便当用户选择选项卡或浏览NavigationControllers时,数据已经存在。

所以我的问题是:

  1. 如何正确传递上下文?
  2. 我应该何时获取数据,即使用哪种方法? “viewDidLoad”或“viewDidAppear”?
  3. 感谢所有想法!

4 个答案:

答案 0 :(得分:10)

您通常应该远离从应用代理获取共享对象。它使它的行为太像一个全局变量,并且有一大堆与之相关的问题。而单身人士只是花哨的全球变量,所以除非真的有必要,否则应该避免它们。

我会为每个视图控制器添加一个managedObjectContext属性,并在创建它们时指定它。这样,您的视图控制器与应用程序委托没有紧密的联系。

至于何时获取数据,你应该懒惰地做。核心数据非常快,所以我要等到viewWillAppear:才能获取。如果等到viewDidAppear:,则视图已经在屏幕上,并且数据加载时会出现闪烁。但请注意,每次您的视图可见时都会调用viewWillAppear:(例如,当用户点击导航栏上的后退按钮或模态视图控制器被解除时),因此您可能需要跟踪是否您已经加载了数据并在后续调用中跳过加载。

答案 1 :(得分:2)

我遇到了同样的问题,我会分享我的解决方案。

首先,你需要在nib文件的Tab栏中引用Nav Controller,确保你连接它。

IBOutlet UINavigationController *navigationController;

然后,按照支持文档中的建议获取Controller,并将其发送到managedObjectContext:

SavedTableViewController *saved = (SavedTableViewController *)[navigationController topViewController];
saved.managedObjectContext = self.managedObjectContext;

Alex是对的,“你通常应该避免从app委托中获取共享对象。它使得它的行为太像一个全局变量,而且它有很多与之相关的问题。”

答案 2 :(得分:0)

您可以随时从应用代表处获取:

myApp *d = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *managedObjectContext = d.managedObjectContext;

或以上的变化。 除此之外,您可以向所有视图控制器添加属性并传递它,或者您可以创建全局的单例和引用。

答案 3 :(得分:0)

夫特

您应该分享NSManagedObjectContext,但可以共享 NSPersistentStoreCoordinator

因此,您可以为每个视图创建一个新的托管对象上下文,每个视图共享同一个商店。它是首选方法,允许并发多线程访问。在下面的示例中,我假设您的AppDelegate,*如果使用最近版本的Xcode创建并使用使用核心数据选中*,则具有名为persistentStoreCoordinator的属性:

lazy var managedObjectContext:NSManagedObjectContext? = {
    // This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.

    if let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate {
        let coordinator = appDelegate.persistentStoreCoordinator
        var managedObjectContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
        managedObjectContext.persistentStoreCoordinator = coordinator
        return managedObjectContext
    }
    }()