Отношения CoreData равны нулю после mergeChangesFromContextDidSaveNotification - PullRequest
3 голосов
/ 24 февраля 2012

По-настоящему странное поведение с Core Data на iOS.

У меня есть NSManagedObjectContext для моего основного потока, используемого для чтения данных из постоянного хранилища SQLLite и их отображения пользователю.У меня также есть фоновые процессы, управляемые NSOperationQueue.Эти фоновые процессы создают NSMangedObjectContext, извлекают данные с удаленных серверов и сохраняют эти данные в локальном хранилище базовых данных.

Я зарегистрировался на NSManagedObjectContextDidSaveNotification, и когда я получаю эти уведомления, я вызываю mergeChangesFromContextDidSaveNotificationв главном потоке NSManagedObjectContext (передавая объект уведомления в качестве аргумента).

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

До недавнего времени я всегда вставлял новые объекты в хранилище данных, а не изменял объекты в хранилище данных.Это работало нормально.После того, как фоновый поток записывает новые данные, происходит слияние, я отправляю уведомление в UIController и перерисовываю свой дисплей.Дисплей отрисовывается правильно.

Недавно я внес изменение, и фоновая нить одновременно вставляет и изменяет объекты.Но все остальное в шаблоне остается прежним.Теперь после слияния данные в моем основном потоке NSManagedObjectContext повреждены.Если я пытаюсь запросить объекты, я ничего не получаю обратно.Если я пытаюсь исследовать объекты, на которые у меня уже есть ссылка, все их отношения равны нулю (не ошибкам, а нулю).Я проверил базу данных SQLLite, и все данные там.

Кажется, что единственное решение - сбросить NSManagedObjectContext, что неприемлемо, учитывая архитектуру приложения.

Ok, последняя странность.Если мой фоновый поток обновляет только атрибуты (примитивы), я не получаю такого странного поведения.Однако если я обновлю сами отношения, то получу эти пустые результаты запроса на выборку и нулевые отношения.

Чего мне не хватает?

1 Ответ

3 голосов
/ 24 февраля 2012

Хорошо, я разобрался в своей проблеме.Моя проблема в том, как mergeChangesFromContextDidSaveNotification объединяет изменения из одного потока в другой.Как я прочитал несколько раз, он не воспроизводит сделанные вами изменения, а объединяет конечное состояние вместе.Я не осознавал последствия этого.В фоновом потоке я удаляю объект, но перед тем как удалить его, я обнуляю некоторые из его отношений, потому что они помечены как каскадное удаление, и я не хочу, чтобы они были удалены.Очевидно, что когда я объединяю эти удаленные объекты в основной контекст, Базовые данные по-прежнему применяют правила удаления, а каскадное удаление связанных объектов в основном контексте.Я изменил свои правила удаления, и теперь мои отношения не выходят неправильно.К сожалению, у меня есть отношения, которые в некоторых случаях я хочу удалить каскадом, а в других - нет.Я должен буду работать над этим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...