Основные данные EXC_BAD_ACCESS при удалении
Получение EXC_BAD_ACCESS при удалении объектов из Core Data. Есть идеи как решить проблему? Может потребоваться некоторое чтение о принципах Core Data (?)
func deleteEntity(_ entity : String) {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
print("Object count: \(context.registeredObjects.count)") // prints 0 here
do {
let results = try context.fetch(fetchRequest)
for managedObject in results {
let managedObjectData : NSManagedObject = managedObject as! NSManagedObject
if !managedObjectData.isDeleted{
context.delete(managedObjectData) // EXC_BAD_ACCESS here, fetch request returns 1 item here!
}
}
try context.save()
} catch let error {
print(error)
}
}
Crashed: com.apple.main-thread
0 CoreData 0x1114c7293 -[NSManagedObjectContext(_NSInternalAdditions) _registerObject:withID:] + 35
1 CoreData 0x1114c5569 -[NSManagedObjectContext(_NSInternalAdditions) _retainedObjectWithID:optionalHandler:withInlineStorage:] + 217
2 CoreData 0x1114d0512 _PF_FulfillDeferredFault + 882
3 CoreData 0x1114dfe9e _PF_Handler_Primitive_GetProperty + 110
4 CoreData 0x1114dfca3 -[NSManagedObject(_NSInternalMethods) _newPropertiesForRetainedTypes:andCopiedTypes:preserveFaults:] + 323
5 CoreData 0x1114dfb39 -[NSManagedObject(_NSInternalMethods) _newAllPropertiesWithRelationshipFaultsIntact__] + 89
6 CoreData 0x1114dfa2b -[NSManagedObjectContext(_NSInternalChangeProcessing) _establishEventSnapshotsForObject:] + 75
7 CoreData 0x1114f7168 -[NSManagedObjectContext deleteObject:] + 136
Изменить: кажется, что-то не так с контекстом. Я также пытался удалить весь магазин, но, похоже, один предмет остался, вызывая сбой. Этот конкретный элемент добавляется позже, в другом представлении. Может быть, это связано с отношениями. Отладка с помощью -com.apple.CoreData.ConcurrencyDebug 1
трассировка стека также показывает
"NSManagedObject может быть только (или наблюдаться) одним NSManagedObjectContext".
2 ответа
Обычный способ удалить все объекты объекта
func deleteEntity(_ entity : String) throws {
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: entity)
let results = try context.fetch(fetchRequest)
for managedObject in results {
context.delete(managedObject)
}
try context.save()
}
Однако в iOS 9+, MacOS 10.11+ есть лучший способ
func deleteEntity(_ entity : String) throws {
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: entity)
let deleteRequest = NSBatchDeleteRequest(fetchRequest: request as! NSFetchRequest<NSFetchRequestResult>)
let persistentStoreCoordinator = context.persistentStoreCoordinator!
try persistentStoreCoordinator.execute(deleteRequest, with: context)
try context.save()
}
Я вижу несколько проблем с вашим кодом...
NSManagedObjectContext.registeredObjects.count
будет считать все объекты в контексте всех сущностей. Это, вероятно, не то, что вы хотите (если только в вашей модели данных нет только одного объекта).- Я не вижу выхода из
do{...}
, managedObjectData
кажется такой же, какmanagedObject
, за исключением объявленного как не ноль, когда фактически это может быть ноль. (Это, вероятно, причина аварии.)- Вам следует позвонить
context.save()
только один раз, после выхода из цикла.
Но вы не должны использовать этот код в любом случае. Вместо этого замените его одним из лучших способов удаления всех объектов данного объекта, как указано в ответах на этот вопрос.