我正在尝试有效地批量删除很多NSManagedObject
s(不使用NSBatchDeleteRequest
)。我一直在遵循一般程序这个答案 https://stackoverflow.com/a/12116402/5513562(适用于 Swift),通过批处理请求对象、删除、保存然后重置上下文的操作。我的获取请求集includesPropertyValues https://developer.apple.com/documentation/coredata/nsfetchrequest/1506387-includespropertyvalues to 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()
, ETC)。我不知道还有什么可能导致这些故障发生。
Update: 我创建了一个简单的例子 https://gist.github.com/AndrewBennet/97ca0686cbae6902aabeda502243557b在 Swift 游乐场。它具有具有单个属性的单个实体,并且没有关系。 Playground 从主线程的 viewContext 中删除托管对象NSPersistentContainer
, a 表明对象属性isFault
变化自true
to false
.
我认为权威的答案需要查看核心数据源代码。由于这不太可能实现,因此我认为这可能是必要的,原因如下。
- 对于具有关系的实体,可能有必要检查关系以处理删除规则并维护数据完整性。例如,如果删除规则是“级联”,则有必要触发故障以确定应删除哪些相关实例。如果它是“无效”,则触发故障以找出哪些相关实例需要将其关系值设置为 nil。
- 除了上述内容之外,具有关系的实体还需要对相关实例执行验证检查。例如,如果您删除具有使用“无效”删除规则的关系的对象,并且反向关系不是可选的,则反向关系的验证检查将失败。检查这一点可能会触发故障。
- 二进制属性可以将数据自动存储在外部文件中(“允许外部存储”选项)。为了清理外部文件,可能需要触发故障,以便知道要删除哪个文件。
我认为所有这些都可以被优化掉。例如,如果实体没有关系并且没有使用外部存储的属性,则不要触发故障。然而,这是从外部看,无法访问源代码。可能还有其他原因需要触发故障。这似乎是有可能的。或者可能没有人尝试过这种优化,无论出于何种原因。这似乎不太可能,但却是可能的。
顺便说一句,我分叉了你的游乐场代码以获得不依赖外部数据模型文件的版本 https://gist.github.com/atomicbird/56e1b3852656541dd9b8ded99bb93445,而是在代码中构建模型。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)