NSManagedObjectContext не может удалять объекты в других контекстах
У меня есть два объекта, каждый из которых отображается в отдельном разделе UITableView.
Я включил редактирование, чтобы позволить пользователю удалять строки, прокручивая вправо. Это отлично работает для первого объекта, но когда я пытаюсь удалить объект во втором объекте, я получаю эту ошибку:
An NSManagedObjectContext cannot delete objects in other contexts
Я понимаю, что говорит ошибка, но я не вижу, как это применимо здесь. Я использую сохраненную ссылку на мой контекст для создания, извлечения и удаления всех объектов из базы данных, поэтому я уверен, что существует только один контекст. Я также не использую несколько потоков. Любая идея, что может произойти?
Ответы
Ответ 1
Является ли контекстом, который вы извлекли NSManagedObject из того же экземпляра, что и контекст, используемый для удаления NSManagedObject? Если нет, вам нужно либо:
- Имейте общую ссылку на тот же NSManagedObjectContext, чтобы вы удалили объект из того же контекста, который вы создали или извлекли из него. Если вы не используете несколько потоков, вам нужно будет только один раз вызвать [[NSManagedObjectContext alloc]] в вашем коде.
или
-
Если вам нужно использовать два разных экземпляра NSManagedObjectContext, затем получите идентификатор объекта из NSManagedObject, который вы получили из первого контекста, чтобы вы могли позже позвонить:
[контекст deleteObject: [context objectWithID: aObjectID]];
NSManagedObjectID совпадает между контекстами, но сам NSManagedObject не является.
Ответ 2
Этот ответ объясняет случай, описанный в комментариях Райли Даттона о том, что сообщение об ошибке вводит в заблуждение.
Сообщение об ошибке будет отображаться при передаче объекта, который не является подклассом NSManagedObject, на deleteObject:
. Райли попал в проблему просто, явно передав неправильный объект, но я попал туда с изменениями Core Data.
Цель моего развертывания для проекта была установлена в 7.0, и этот код работал без ошибок даже на iOS 9.3:
NSArray *entries = @[self.colorList.colors, self.emotionList.emotions, self.shapeList.shapes];
for (id entry in entries) {
[[self managedObjectContext] deleteObject:entry];
}
Когда я обновил цель развертывания проекта до 9.3, я начал получать сообщение об ошибке.
Вот описание entry
:
Relationship 'colors' fault on managed object (0x7fd063420310) <MyColorList: 0x7fd063420310> (entity: MyColorList; id: 0xd000000000640006 <x-coredata://12556DEF-F77E-4EFF-AAE6-55E71A3F5420/MyColorList/p25> ; data: {
attachedThing = "0xd0000000000c0004 <x-coredata://12556DEF-F77E-4EFF-AAE6-55E71A3F5420/MyThing/p3>";
colors = "<relationship fault: 0x7fd063468f30 'colors'>";
})
Похоже, что Apple изменила правила, когда Core Data вызовет ошибку и фактически вытащит данные из постоянного координатора хранилища.
Эта модификация решила проблему:
NSArray *entries = @[self.colorList.colors, self.emotionList.emotions, self.shapeList.shapes];
for (id entry in entries) {
for (id e in entry) {
[[self managedObjectContext] deleteObject:e];
}
}
В настоящее время я не знаю, является ли это идеальным способом решения этой проблемы или существует более канонический способ сообщить Core Data о возникновении ошибки и прочитать данные с диска.
Ответ 3
Я использую это:
func delete(object: YourManagedObject) {
guard let context = object.managedObjectContext else { return }
if context == self.viewContext {
context.delete(object)
} else {
self.performBackgroundTask { context in
context.delete(object)
}
}
try? self.viewContext.save()
}
В принципе, вполне вероятно, что объект, который вы хотите удалить, был предоставлен viewContext для NSPersistentContainer. Поэтому попытка удалить из частного фонового контекста не будет работать.
Ответ 4
Хорошо, попробуйте это; это может решить вашу проблему: -
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
//delete Entity
});
то получилась та же ошибка.
После попытки удалить объект в основном потоке, и эта проблема исправлена.