我使用Core Data在本地持久化Web服务调用的结果。web服务返回完整的对象模型,比如说,“Cars”——可能有2000辆车(我不能让web服务返回小于1辆或ALL辆的任何东西。
下次打开应用程序时,我希望通过再次调用所有汽车的Web服务来刷新Core Data持久化副本,但是为了防止重复,我需要首先清除本地缓存中的所有数据。
是否有一种更快的方法来清除管理对象上下文中特定实体的所有实例(例如,类型为“CAR”的所有实体),或者我需要查询它们调用,然后遍历结果删除每个,然后保存?
理想情况下,我可以说删除实体所在的所有地方等等。
Swift 3解决方案与iOS 9 'NSBatchDeleteRequest'和回退到早期的iOS版本,作为'NSManagedObjectContext'的扩展实现。苹果参考https://developer.apple.com/library/content/featuredarticles/CoreData_Batch_Guide/BatchDeletes/BatchDeletes.html
extension NSManagedObjectContext {
func batchDeleteEntities<T: NSManagedObject>(ofType type: T.Type) throws {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: String(describing: type.self))
if #available(iOS 9.0, *) {
let request = NSBatchDeleteRequest(fetchRequest: fetchRequest)
let result = try execute(request) as? NSBatchDeleteResult
if let objectIDArray = result?.result as? [NSManagedObjectID] {
let changes = [NSDeletedObjectsKey: objectIDArray]
NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [self])
}
} else {
fetchRequest.includesPropertyValues = false
let results = try fetch(fetchRequest)
if let actualResults = results as? [NSManagedObject], !actualResults.isEmpty {
actualResults.forEach { delete($0) }
}
}
}
}
Swift 4, iOS 10+
静态函数,可以应用于任何实体删除其所有数据
protocol NSManagedObjectHelper {
}
extension NSManagedObject: NSManagedObjectHelper {
}
extension NSManagedObjectHelper where Self: NSManagedObject {
static func removeAllObjectsInContext(_ managedContext: NSManagedObjectContext) {
let request: NSFetchRequest = NSFetchRequest(entityName: String(describing: self))
let deleteRequest = NSBatchDeleteRequest(fetchRequest: request)
do {
deleteRequest.resultType = .resultTypeObjectIDs//to clear objects from memory
let result = try managedContext.execute(deleteRequest) as? NSBatchDeleteResult
if let objectIDArray = result?.result as? [NSManagedObjectID] {
let changes = [NSDeletedObjectsKey : objectIDArray]
/*By calling mergeChangesFromRemoteContextSave, all of the NSManagedObjectContext instances that are referenced will be notified that the list of entities referenced with the NSManagedObjectID array have been deleted and that the objects in memory are stale. This causes the referenced NSManagedObjectContext instances to remove any objects in memory that are loaded which match the NSManagedObjectID instances in the array.*/
NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [managedContext])
}
try managedContext.save()
} catch let error {
print(error)
}
}
}
“房间”是一个实体
Room.removeAllObjectsInContext(self.persistentContainer.viewContext)
在20191025编辑:如果我们在同一个项目中使用多个目标,"Self.fetchRequest()"指令可能会导致问题。所以替换为NSFetchRequest(entityName: String(description: self))