Копирование ожидающих изменений между NSManagedObjectContexts с общим постоянным хранилищем? - PullRequest
5 голосов
/ 16 марта 2012

У меня есть два экземпляра NSManagedObjectContext: один используется в основном потоке, а другой - в фоновом потоке (через NSOperation.) В целях обеспечения безопасности потока эти два контекста имеют только NSPersistentStoreCoordinator.

Проблема, с которой я столкнулся, заключается в том, что ожидающие изменения в первом контексте (в основном потоке) недоступны для второго контекста, пока не будет выполнено -save. Это понятно, поскольку в общем постоянном хранилище не будет сохранено копий NSManagedObjects, отслеживаемых -insertedObjects, -updatedObjects и -deletedObjects.

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

Единственное решение, которое я могу придумать, это противное: взять вставленные, обновленные и удаленные объекты из первого контекста и перенести их на граф объектов второго контекста. В наборе данных есть довольно сложные отношения, поэтому я не решаюсь идти в этом направлении. Я надеюсь, что кто-то здесь, как лучшее решение.

Ответы [ 4 ]

4 голосов
/ 16 марта 2012

Если это значение меньше 10.7, есть несколько решений: во-первых, вы можете иметь вложенный ManagedObjectContexts, так что вы можете «сохранить» в изменяемом файле, и он не сохранится полностью на диск, но это сделает изменения доступны другим дочерним элементам основного контекста.

До 10.7 вам, вероятно, придется скопировать изменения на себя. Это не очень сложно, так как вы можете просто прослушать один объект для NSManagedObjectContextObjectsDidChangeNotification, а затем просто повторно применить изменения точно из основного контекста. (Должно быть около 20 строк кода.) Вам никогда не придется сохранять этот второй контекст, который я предполагаю?

2 голосов
/ 16 марта 2012

Не уверен, если у вас есть какие-либо ограничения ОС, но в iOS 5 / Mac OS 10.7 вы можете использовать вложенные контексты управляемого объекта для достижения этой цели.Я полагаю, что дочерний контекст способен извлекать несохраненные изменения в родительском элементе, просто делая новую выборку.

Редактировать: Похоже, что Вил побил меня, но да, до iOS 5/ Mac OS 10.7 вам нужно будет прослушать NSManagedObjectContextDidSaveNotification и взглянуть на словарь userInfo для добавленных / обновленных / удаленных объектов.

0 голосов
/ 18 марта 2012

Я бы попытался сделать основной поток обычным сохранением, чтобы второй контекст мог просто объединить изменения с его контекстом.«Борьба» с использованием API по назначению никогда не была хорошей идеей.Вы можете пометить вновь сохраненную запись с атрибутом как промежуточный и удалить позже, если пользователь наконец отменит редактирование.

Решение этих проблем с атрибутами в ваших сущностях и запрос в фоновом потоке с предикатом сопоставления было бы легко ...

И это также было бы стабильным решением.Я пришел из мира, управляемого базой данных (оракул), мы часто используем такие шаблоны (атрибуты статуса в записях), чтобы сделать данные видимыми / невидимыми для других сеансов БД (которые будут равны потокам в приложении какао).Работает всегда без проблем.Другие потоки / сеансы всегда видят только зафиксированные изменения, так работает большинство СУБД.

0 голосов
/ 16 марта 2012

Альтернативное решение может включать использование одного контекста управляемого объекта и обеспечение собственной безопасности потока при доступе к нему или использование методов блокировки и разблокировки контекста.

...