我使用Core Data在本地持久化Web服务调用的结果。web服务返回完整的对象模型,比如说,“Cars”——可能有2000辆车(我不能让web服务返回小于1辆或ALL辆的任何东西。

下次打开应用程序时,我希望通过再次调用所有汽车的Web服务来刷新Core Data持久化副本,但是为了防止重复,我需要首先清除本地缓存中的所有数据。

是否有一种更快的方法来清除管理对象上下文中特定实体的所有实例(例如,类型为“CAR”的所有实体),或者我需要查询它们调用,然后遍历结果删除每个,然后保存?

理想情况下,我可以说删除实体所在的所有地方等等。


当前回答

上面的答案很好地说明了如何删除“Cars”。

然而,我想用这个答案来挑战这种方法本身:

1- SQLite CoreData是一个关系数据库。在这种情况下,如果没有任何关联,我建议不要使用CoreData,而改用文件系统,或者将数据保存在内存中。

2-在其他例子中,“Car”实体有其他关系,因此CoreData,我建议不要把2000辆车作为根实体。相反,我会给它们一个父实体,比如说"CarsRepository"实体。然后,您可以给“Car”实体一个一对多的关系,只需在下载新车时替换该关系以指向新车。向关系中添加正确的删除规则可以确保模型的完整性。

其他回答

延续戴夫·德隆的回答。

Swift版本,照顾iOS 9和以前的版本以及。我还介绍了错误处理:

let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as!应用委托

    let fetchRequest = NSFetchRequest(entityName: "Car")
    if #available(iOS 9.0, *) {
        let delete = NSBatchDeleteRequest(fetchRequest: fetchRequest)
        do {
            try appDelegate.persistentStoreCoordinator.executeRequest(delete, withContext: appDelegate.managedObjectContext)
        } catch let error as NSError {
            print("Error occured while deleting: \(error)")
        }
    } else {
        // Fallback on earlier versions
        let carRequest = NSFetchRequest()
        carRequest.entity = NSEntityDescription.entityForName("Cars", inManagedObjectContext: appDelegate.managedObjectContext)
        carRequest.includesPropertyValues = false

        do {
            let cars: NSArray = try appDelegate.managedObjectContext.executeFetchRequest(carRequest)

            for car in cars {
                appDelegate.managedObjectContext.delete(car)
            }

            try appDelegate.managedObjectContext.save()

        } catch let error as NSError {
            print("Error occured while fetching or saving: \(error)")
        }
    }

iOS 9.0及以上版本:

NSBatchDeleteRequest用于删除核心数据中的记录。它的工作速度非常快,从一个实体删除所有记录所需的时间更少。它需要NSFetchRequest作为参数。如果你想从一个实体删除所有记录,你可以使用它,它为我工作。

let manageObject:NSManagedObjectContext = appDelegateObject.managedObjectContext

let fetchRequest = NSFetchRequest(entityName: “EnityName”)

let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)

let persistCor:NSPersistentStoreCoordinator = appDelegateObject.persistentObject
 do {
        try persistCor.executeRequest(deleteRequest, withContext: manageObject)
        try manageObject.save()
    } catch {
        print(error?.localizedDescription)
    }

对于Swift 2.0:

class func clearCoreData(entity:String) {
  let fetchRequest = NSFetchRequest()
  fetchRequest.entity = NSEntityDescription.entityForName(entity, inManagedObjectContext: moc!)
  fetchRequest.includesPropertyValues = false
  do {
    if let results = try moc!.executeFetchRequest(fetchRequest) as? [NSManagedObject] {
      for result in results {
        moc!.deleteObject(result)
      }

      try moc!.save()
    }
  } catch {
    LOG.debug("failed to clear core data")
  }
}

Swift 4, iOS 12和Xcode 10更新

100%工作,只是剪切和粘贴

只要把这个函数放在相关的类中,并在viewDidLoad()或任何地方或在一个函数或按钮下调用这个函数self.deleteData(),这样通过单击一个按钮,所有来自实体的数据都应该被删除,并替换“myEntity”作为你在核心数据中定义的实体

func deleteData() {
    let appDel:AppDelegate = (UIApplication.shared.delegate as! AppDelegate)
    let context:NSManagedObjectContext = appDel.persistentContainer.viewContext
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "myEntity")
    fetchRequest.returnsObjectsAsFaults = false         
    do {
        let results = try context.fetch(fetchRequest)
        for managedObject in results {
            if let managedObjectData: NSManagedObject = managedObject as? NSManagedObject {
                context.delete(managedObjectData)
            }
        }
    } catch let error as NSError {
        print("Deleted all my data in myEntity error : \(error) \(error.userInfo)")
    }
}

Dave Delongs的Swift 2.0回答让我崩溃了(在iOS 9中)

但这个方法奏效了:

let fetchRequest = NSFetchRequest(entityName: "Car")
let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)

    do {
        try managedObjectContext.executeRequest(deleteRequest)
        try managedObjectContext.save()
    }
    catch let error as NSError {
       // Handle error
    }