在多个视图控制器中使用FetchedResultsController和ManagedObjectContext

时间:2011-07-19 06:27:46

标签: ios core-data uiviewcontroller nsfetchedresultscontroller

我的RootViewController包含一个简单的表视图。选择表中的一个条目后,将显示DetailViewController,其中包含有关所选条目的更多详细信息。相关数据对象的数据通过CoreData加载和保存。如何在didSelectRowAtIndexPath:方法中将FetchedResultsController和ManagedObjectContext传递给DetailViewController? 我是否需要在DetailViewController.h中为两者定义属性?你能给我一个代码示例吗?

2 个答案:

答案 0 :(得分:19)

首先,每个获取结果控制器(FRC)实例都是针对每个tableview配置的,因此您不会将FRC从tableview控制器传递到tableview控制器。相反,每个tableview控制器都专门为其tableview实例化和配置新的FRC。

在主视图的主视图设计中,您不会将FRC传递给详细视图,而只传递由所选tableview行表示的单个托管对象。

Apple建议通过“依赖注入”传递托管对象上下文(MOC)。这很简单。在最常见的设计中,您在应用程序委托中初始化MOC,然后为每个视图控制器提供managedObjectContext属性。然后,当您加载/推送视图控制器时,只需将其managedObjectContext属性设置为MOC。

例如,在Master-Detail设计中,您通常有一个导航控制器(NAV)。要了解其工作原理,请使用Xcode中基于导航的应用模板创建测试应用。标记它以使用核心数据。您将认为应用委托和RootViewController都具有managedObjectContext属性。

现在在app delegate的applicationDidFinishLaunching:...方法中添加代码使其看起来像:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  // Override point for customization after application launch.
  // Add the navigation controller's view to the window and display.
  RootViewController *topVC=(RootViewController *) self.navigationController.topViewController;
  topVC.managedObjectContext=self.managedObjectContext;
  self.window.rootViewController = self.navigationController;
  [self.window makeKeyAndVisible];
    return YES;
}

...然后在RootViewController.m添加:

- (void)viewDidAppear:(BOOL)animated
{
  NSLog(@"self.managedObjectContext = %@",self.managedObjectContext);
  [super viewDidAppear:animated];
}

运行测试应用时,RootViewController对象会将其managedObjectContext属性记录为:

2011-07-19 09:24:05.193 CDNavTemplate[3203:207] self.managedObjectContext = <NSManagedObjectContext: 0x4d318a0>

...证明RootViewController对象具有来自app delegate的托管对象上下文。

现在,您只需为推送到导航控制器堆栈的每个视图控制器重复此过程,逐步将相同的托管对象上下文对象向下移动到视图层次结构中。您可以以完全相同的方式传递任何其他类型的对象。

Apple建议使用依赖注入,因为它使代码更加模块化,并且可以在单个应用程序中轻松使用多个托管对象上下文。您只需在任何特定时间传递每个特定视图控制器所需的特定上下文。

答案 1 :(得分:1)

简而言之,有两种选择:

  1. 这两个(FetchedResultsController和ManagedObjectContext)都需要位于所有视图控制器都可以访问它们的位置。例如,如果它们位于App Delegate中(默认情况下Xcode放置ManagedObjectContext),您可以以这种方式访问​​它(这将显示警告 - 因此您需要键入应用程序的app delegate类的委托) :
  2. NSManagedObjectContext *context = [[[UIApplication sharedApplication] delegate] managedObjectContext];
    1. 实际上,您可以在创建视图控制器时将这些值传递给视图控制器。例如,您可以创建一个子类(例如DataViewController或其他东西),并在此子类(对于ManagedObjectContext和FetchedResultsController)上有两个属性,这些属性将在您创建时设置。