Подтвердить что ты не робот

Должен ли родительский объект Core Data ManagedObjectContext обмениваться типом concurrency с детским контекстом?

Можно ли установить родительский контекст моего ManagedObjectContext в ManagedObjectContext с другим типом concurrency? Например:

backgroundManagedObjectContext_ = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[backgroundManagedObjectContext_ setPersistentStoreCoordinator:coordinator];
managedObjectContext_ = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[managedObjectContext_ setParentContext:backgroundManagedObjectContext_];

Моя цель состоит в том, чтобы (надеюсь) получить быстрое сохранение для managedObjectContext_ (так как это нужно только для сохранения вещей в родительский контекст в памяти), а затем backgroundManagedObjectContext_ сохранить в собственной очереди. Если мне не понадобится сделать еще одно сохранение из очереди "переднего плана" до того, как фон сохранит моего пользователя, он никогда не увидит длительное время сохранения.

Я сталкиваюсь с тем, что выглядит как тупики, но я не уверен, связаны ли они с этим, или если моя проблема в другом месте.


Подробности для одного места, где я могу более или менее надежно создать тупик:

У меня есть контекст управляемого объекта для основного потока, он поддерживается контекстом управляемого объекта с типом частной очереди concurrency, и у него есть постоянное хранилище.

У меня есть несколько типов сущностей (около 5), каждый с одним или двумя двунаправленными отношениями с другим объектом.

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

Итак, когда я вижу пустую базу данных (это проверяется в основном потоке), я добавляю около 4 или 8 всех, кроме одного из типов сущностей, а последний получает около 100 (все добавления происходят на основной нить). Основной поток выполняет saveContext. После этого (без ошибок) он запрашивает, чтобы другой контекст управляемого объекта запускал блок, который также выполняет saveContext. Этот saveContext определенно является участником взаимоблокировки. Это также ТОЛЬКО материал, сделанный с помощью "фона" NSManagedObjectContext.

Точный поток управления немного мутноват после этого, как NSFetchedResultsController (весь тип сущности (который имеет ~ 3 члена) с простым сортировкой и размером партии 20 или около того) приводит в следующий раунд Core Data, но есть вызов от TableViewController, спрашивающий, сколько элементов ему нужно управлять, а именно "сколько результатов имеет получаемый контроллер результатов". Этот вызов является другой стороной тупика. (все это в основном потоке)

4b9b3361

Ответ 1

Из моего опыта это не является необходимым, если оба контекста реализуют либо NSMainQueueConcurrencyType, либо NSPrivateQueueConcurrencyType. Важно помнить, что при взаимодействии с контекстами управляемых объектов для нескольких потоков все сообщения, отправленные в контекст, должны быть отправлены через -performBlock: или performBlockAndWait:.

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

// Save the child context first
[childContext performBlock:^{
    NSError *error = nil;
    [childContext save:&error];

    // Save the changes on the main context
    [parentContext performBlock:^{
        NSError *parentError = nil;
        [parentContext save:&parentError];
    }];
}];

Теперь я не могу с уверенностью сказать, что это правильный способ сделать это, потому что документация по этому вопросу довольно редкая на данный момент. Возможно, было бы полезно, если бы вы могли показать код, который, по вашему мнению, вызывает взаимоблокировки. Если вы находитесь в программе разработчика, вы можете проверить видеозапись сеанса WWDC относительно основных данных с этого года. Я считаю, что есть два, один для Mac OS X и один для iOS, которые в основном касаются одних и тех же идей, но каждый также содержит уникальную информацию.