Использование FetchedResultsController и ManagedObjectContext в нескольких контроллерах представления - PullRequest
5 голосов
/ 19 июля 2011

Мой RootViewController содержит простое табличное представление.При выборе одной из записей в таблице отображается DetailViewController с более подробной информацией о выбранной записи.Данные соответствующего объекта данных загружаются и сохраняются через CoreData.Как передать FetchedResultsController и ManagedObjectContext в DetailViewController в didSelectRowAtIndexPath: метод?Нужно ли определять свойства для обоих в DetailViewController.h?Можете ли вы предоставить мне пример кода?

Ответы [ 2 ]

19 голосов
/ 19 июля 2011

Во-первых, каждый экземпляр контроллера извлеченных результатов (FRC) настраивается отдельно для каждого просмотра таблицы, поэтому вы не передаете FRC из контроллера просмотра таблицы в контроллер просмотра таблицы. Вместо этого каждый контроллер табличного представления создает и настраивает новый FRC специально для своего табличного представления.

В проекте Master-Detail, где табличное представление является главным представлением, вы не передаете FRC в подробное представление, а вместо этого только один управляемый объект, который представлен выбранной строкой табличного представления.

Apple рекомендует, чтобы контекст управляемого объекта (MOC) передавался посредством «внедрения зависимостей». Это очень просто. В наиболее распространенной схеме вы инициализируете MOC в делегате приложения, а затем предоставляете каждому из ваших контроллеров представления свойство managedObjectContext. Затем, когда вы загружаете / выдвигаете контроллер представления, вы просто устанавливаете его свойство managedObjectContext в MOC.

Например, в проекте Master-Detail у вас обычно есть навигационный контроллер (NAV). Чтобы увидеть, как это работает, создайте тестовое приложение, используя шаблон приложения на основе навигации в XCode. Отметьте это, чтобы использовать Базовые Данные. Вам будет необходимо, чтобы и делегат приложения, и RootViewController имели свойство managedObjectContext.

Теперь в методе делегата приложения 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 имеет контекст управляемого объекта от делегата приложения.

Теперь вы просто повторяете процесс для каждого контроллера представления, который вы помещаете в стек контроллеров навигации, постепенно передавая один и тот же объект контекста управляемого объекта вниз по иерархии представления. Вы можете передать любой другой тип объекта точно так же.

Apple рекомендует внедрение зависимостей, поскольку это делает код более модульным и упрощает использование контекста нескольких управляемых объектов в одном приложении. Вы просто передаете каждому конкретному контроллеру представления конкретный контекст, в котором он нуждается в любое конкретное время.

1 голос
/ 19 июля 2011

Короче говоря, есть два варианта:

  1. Оба из них (FetchedResultsController и ManagedObjectContext) должны находиться в месте, где все контроллеры представления могут получить к ним доступ. Например, если они находятся в делегате приложения (где XCode размещает ManagedObjectContext по умолчанию), вы можете получить к нему доступ таким образом (это покажет предупреждение - поэтому вам нужно будет ввести делегат в класс делегата приложения вашего приложения) :
NSManagedObjectContext *context = [[[UIApplication sharedApplication] delegate] managedObjectContext];
  1. Вы могли бы фактически передать эти значения в ваши контроллеры представления при их создании. Например, вы можете создать подкласс (например, DataViewController или что-то еще) и иметь два свойства в этом подклассе (для ManagedObjectContext и FetchedResultsController), которые будут установлены при их создании.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...