我正在尝试有效批量删除大量NSManagedObject
s(不使用NSBatchDeleteRequest
)。我一直在遵循this answer(适用于Swift)中的一般过程,通过批处理请求对象,删除,保存然后重置上下文的操作。我的抓取请求将includesPropertyValues
设置为false
。
但是,当此操作运行时,在从上下文中删除每个对象的位置,将触发该错误。添加日志记录如下:
// Fetch one object without property values
let f = NSFetchRequest<NSManagedObject>(entityName: "Entity")
f.includesPropertyValues = false
f.fetchLimit = 1
// Get the result from the fetch. This will be a fault
let firstEntity = try! context.fetch(f).first!
// Delete the object, watch whether the object is a fault before and after
print("pre-delete object is fault: \(firstEntity.isFault)")
context.delete(firstEntity)
print("post-delete object is fault: \(firstEntity.isFault)")
产生输出:
pre-delete object is fault: true
post-delete object is fault: false
即使没有任何CoreData方法的覆盖(willSave()
,prepareForDeletion()
,validateForUpdate()
等),也会发生这种情况。我无法弄清楚还有什么可能导致这些错误发生。
更新:我在Swift游乐场中创建了simple example。这个实体只有一个属性,没有关系。操场从NSPersistentContainer
的viewContext中删除主线程上的托管对象,演示对象属性isFault
从true
更改为false
。
答案 0 :(得分:2)
我认为权威的答案需要查看核心数据源代码。由于这不太可能即将到来,我可以想到这可能是必要的一些原因。
我认为所有这些都可能会被优化掉。例如,如果实体没有关系且没有使用外部存储的属性,则不要触发故障。但是,这是从外部看,无法访问源代码。可能还有其他原因需要解决故障。这似乎很可能。或者无论出于何种原因,没有人会尝试这种优化。这似乎不太可能,但可能。
BTW我将您的游乐场代码分叉以获取a version that doesn't rely on an external data model file,而是在代码中构建模型。
答案 1 :(得分:1)
Tom Harrington 最好地解释了它。 CoreData的内部实现显然需要在标记要从持久性存储中删除的对象时触发错误,就像访问对象的属性时一样。正如本answer中所述,“NSManagedObject始终是动态呈现的。因此,如果删除它,Core Data将排除数据”。
这似乎是至少暂时的正常行为,而不是真正的问题。