Сегодня я прочитал о похожей проблеме на форумах разработчиков Apple. Возможно, это та же проблема, что и у вас, https://devforums.apple.com/message/666492#666492, и в этом случае, возможно, есть ошибка (или, по крайней мере, кто-то еще с такой же проблемой, чтобы обсудить ее!).
Предполагая, что это не так, похоже, что то, что вы хотите сделать, должно быть вполне возможно с вложенными контекстами и, следовательно, при условии отсутствия ошибок с UIManagedDocument
.
Моя единственная оговорка заключается в том, что я пытался заставить пакетную загрузку работать с UIManagedDocument
, и похоже, что она не работает с вложенными контекстами (https://stackoverflow.com/q/11274412/1347502). Я думаю, что одним из основных преимуществ NSFetchedResultsController
является его способность повышать производительность за счет пакетной загрузки. Так что, если это невозможно сделать в UIManagedDocument
, возможно, NSFetchedResultsController
не готово для использования с UIManagedDocument
, но я еще не дошел до сути этой проблемы.
Помимо этой оговорки, большая часть инструкций, которые я читал или просматривал о вложенных контекстах и фоновой работе, похоже, выполнялись с равноправными дочерними контекстами. То, что вы описали, - это родительская, дочерняя, внучатая конфигурация. В видео WWDC 2012 «Session 214 — Core Data Best Practices» (+ 16:00 минут) Apple рекомендует добавить еще один одноранговый контекст в родительский контекст для этого сценария, например
backgroundContext.parentContext = document.managedObjectContext.parentContext;
В этом контексте работа выполняется асинхронно, а затем передается родительскому объекту с помощью вызова сохранения в фоновом контексте. Затем родитель будет сохранен асинхронно, и любые одноранговые контексты, в данном случае document.managedObjectContext
, получат доступ к изменениям через выборку, слияние или обновление. Это также описано в документации UIManagedDocument
:
- При необходимости вы можете загружать данные из фонового потока непосредственно в родительский контекст. Вы можете получить родительский контекст, используя parentContext. Загрузка данных в родительский контекст означает, что вы не нарушаете операции дочернего контекста. Вы можете получить данные, загруженные в фоновом режиме, просто выполнив выборку.
[Редактировать: перечитывая это, вы можете просто порекомендовать предложение Джеффри, то есть вообще не создавать никаких новых контекстов, а просто использовать родительский контекст.]
При этом документация также предполагает, что обычно вы не вызываете сохранение в дочерних контекстах, а используете методы сохранения UIManagedDocument
. Это может быть случай, когда вы вызываете save или, возможно, часть проблемы. Вызов сохранения в родительском контексте настоятельно не рекомендуется, как упоминал Джеффри. Другой ответ, который я прочитал о переполнении стека, рекомендовал использовать только updateChangeCount
для запуска сохранения UIManagedDocument
. Но я ничего не читал от Apple, поэтому, возможно, в этом случае будет уместно вызвать метод UIManagedDocument saveToURL:forSaveOperation:completionHandler:
, чтобы все синхронизировать и сохранить.
Я предполагаю, что следующая очевидная проблема заключается в том, как уведомить NSFetchedResultsController о произошедших изменениях. У меня возникло бы искушение упростить настройку, как обсуждалось выше, а затем подписаться на различные NSManagedObjectContextObjectsDidChangeNotification
или сохранить уведомления в разных контекстах и посмотреть, какие, если таковые имеются, вызываются, когда UIMangedDocument
сохраняет, автосохраняет или когда фоновые изменения сохраняются в родительском ( допустимо в данном случае). Я предполагаю, что NSFetchedResultsController
подключен к этим уведомлениям, чтобы синхронизироваться с базовыми данными.
В качестве альтернативы, возможно, вам нужно вручную выполнить выборку, слияние или обновление в основном контексте, чтобы получить изменения, а затем каким-то образом уведомить NSFetchedResultsController
о необходимости обновления?
Лично мне интересно, готово ли UIManagedDocument
для общего пользования, на WWDC в этом году о нем не упоминалось, и вместо этого было представлено продолжительное обсуждение того, как создать гораздо более сложное решение: «Сессия 227 — Использование iCloud с Core Data»
person
Rory O'Bryan
schedule
06.07.2012