删除/重置核心数据中的所有条目?

您知道有什么方法可以删除存储在Core Data中的所有条目吗?我的schema应该保持不变;我只想把它重置为空白。


编辑

我希望以编程方式做到这一点,以便用户基本上可以点击reset按钮。

165288 次浏览

删除持久存储文件并设置一个新的持久存储协调器?

你可以删除SQLite文件-但我选择通过一个函数单独清除表来做到这一点:

- (void) deleteAllObjects: (NSString *) entityDescription  {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityDescription inManagedObjectContext:_managedObjectContext];
[fetchRequest setEntity:entity];


NSError *error;
NSArray *items = [_managedObjectContext executeFetchRequest:fetchRequest error:&error];
[fetchRequest release];




for (NSManagedObject *managedObject in items) {
[_managedObjectContext deleteObject:managedObject];
DLog(@"%@ object deleted",entityDescription);
}
if (![_managedObjectContext save:&error]) {
DLog(@"Error deleting %@ - error:%@",entityDescription,error);
}


}

我选择逐表执行的原因是,它使我在编程时确认删除表的内容是合理的,并且没有我宁愿保留的数据。

这样做会比仅仅删除文件慢得多,如果我这个方法花费太长时间,我将更改为文件删除。

从fileURLPath中删除sqlite,然后构建。

您仍然可以使用NSFileManager:removeItemAtPath::方法以编程方式删除该文件。

NSPersistentStore *store = ...;
NSError *error;
NSURL *storeURL = store.URL;
NSPersistentStoreCoordinator *storeCoordinator = ...;
[storeCoordinator removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtPath:storeURL.path error:&error];

然后,只需将持久存储添加回去,以确保正确地重新创建它。

遍历每个实体的编程方式既慢又容易出错。这样做的用途是如果您想删除一些实体而不是其他实体。然而,您仍然需要确保您保留了引用完整性,否则您将无法持久您的更改。

仅仅删除存储并重新创建它既快速又安全,当然可以在运行时以编程方式完成。

iOS5+更新

随着iOS 5和OS X 10.7引入外部二进制存储(allowsExternalBinaryDataStorage或Store in external Record File),简单地删除由storeurl指向的文件是不够的。你会留下外部记录文件。由于这些外部记录文件的命名方案不是公开的,所以我还没有一个通用的解决方案。- 12年5月8日23:00

我写了一个clearStores方法,它遍历每个存储,并从协调器和文件系统中删除它(不考虑错误处理):

NSArray *stores = [persistentStoreCoordinator persistentStores];


for(NSPersistentStore *store in stores) {
[persistentStoreCoordinator removePersistentStore:store error:nil];
[[NSFileManager defaultManager] removeItemAtPath:store.URL.path error:nil];
}


[persistentStoreCoordinator release], persistentStoreCoordinator = nil;

这个方法在coreDataHelper类中,它负责在persistentStore为nil时创建persistentStore。

MagicalRecord使得这非常简单。

[MyCoreDataObject MR_truncateAll];

作为一个快速参考,以节省在其他地方搜索-删除后重新创建持久存储可以用:

if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
// do something with the error
}
我删除了HomeViewController类中一个按钮事件的核心数据中的所有数据: 这篇文章对我帮助很大,我想我也会有所贡献
-(IBAction)buttonReset:(id)sender
{
NSLog(@"buttonReset Pressed");


//Erase the persistent store from coordinator and also file manager.
NSPersistentStore *store = [self.persistentStoreCoordinator.persistentStores lastObject];
NSError *error = nil;
NSURL *storeURL = store.URL;
[self.persistentStoreCoordinator removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:&error];




NSLog(@"Data Reset");


//Make new persistent store for future saves   (Taken From Above Answer)
if (![self.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
// do something with the error
}


}

注意,为了调用self。我在主视图控制器中声明了一个属性。(不要担心我用来保存和加载的managedObjectContext。)

@property (nonatomic, retain) NSManagedObjectContext        *   managedObjectContext;
@property (nonatomic, retain) NSPersistentStoreCoordinator  *   persistentStoreCoordinator;

然后在AppDelegate ApplicationDidFinishLaunching下面创建一个HomeViewController:

homeViewController = [[HomeViewController alloc] initWithNibName:@"HomeViewController" bundle:nil];
homeViewController.managedObjectContext = self.managedObjectContext;
homeViewController.persistentStoreCoordinator = self.persistentStoreCoordinator;

谢谢你的帖子。我遵循了它,它对我很有效。但我有另一个问题,在任何回复中都没有提到。所以我不确定是不是只有我一个人。

不管怎样,我想我应该把这个问题和我解决它的方法贴在这里。

我在数据库中有一些记录,我想在写新数据到db之前清除所有的东西,所以我做了包括

[[NSFileManager defaultManager] removeItemAtURL:storeURL error:&error];

,然后使用managedObjectContext访问数据库(现在应该是空的),不知何故数据仍然在那里。 经过一段时间的故障排除后,我发现我需要重置managedObjectContextmanagedObjectmanagedObjectModelpersistentStoreCoordinator,在我使用managedObjectContext访问dabase之前。现在我有了一个可以写入的干净数据库。< / p >

你们都把事情搞复杂了。你可以发送你的NSManagedObjectContext重置方法

这个问题有几个很好的答案。这里有一个简洁的例子。前两行删除sqlite数据库。然后for:循环删除managedObjectContext内存中的任何对象。

NSURL *storeURL = [[(FXYAppDelegate*)[[UIApplication sharedApplication] delegate] applicationDocumentsDirectory] URLByAppendingPathComponent:@"AppName.sqlite"];
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil];
for (NSManagedObject *ct in [self.managedObjectContext registeredObjects]) {
[self.managedObjectContext deleteObject:ct];
}

下面是一个稍微简化的版本,减少了对AppDelegate self的调用,并且去掉了排名最高的答案中的最后一点代码。此外,我得到了一个错误“对象的持久存储无法从这个NSManagedObjectContext的协调器”,所以只需要添加回来。

NSPersistentStoreCoordinator *storeCoordinator = [self persistentStoreCoordinator];
NSPersistentStore *store = [[storeCoordinator persistentStores] lastObject];
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"dataModel"];
NSError *error;


[storeCoordinator removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtPath:storeURL.path error:&error];


[_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error];


if (storeCoordinator != nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:storeCoordinator];
}

您还可以查找所有实体名称,并按名称删除它们。它是一个较长的版本,但工作得很好,这样你就不必使用持久性存储

 - (void)clearCoreData
{
NSError *error;
NSEntityDescription *des = [NSEntityDescription entityForName:@"Any_Entity_Name" inManagedObjectContext:_managedObjectContext];
NSManagedObjectModel *model = [des managedObjectModel];
NSArray *entityNames = [[model entities] valueForKey:@"name"];


for (NSString *entityName in entityNames){


NSFetchRequest *deleteAll = [NSFetchRequest fetchRequestWithEntityName:entityName];
NSArray *matches = [self.database.managedObjectContext executeFetchRequest:deleteAll error:&error];


}
if (matches.count > 0){
for (id obj in matches){


[_managedObjectContext deleteObject:obj];
}
[self.database.managedObjectContext save:&error];
}
}

对于“Any_Entity_Name”,只需要给出任何一个实体的名称,我们只需要找出实体的实体描述。ValueForKey@"name"将返回所有实体名称。最后,别忘了保存。

如果你想删除所有对象(这比拆除Core Data堆栈简单得多,但性能较差),那么这是一个更好的实现:

- (void)deleteAllManagedObjectsInModel:(NSManagedObjectModel *)managedObjectModel context:(NSManagedObjectContext *)managedObjectContext
{
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
[managedObjectContext performBlockAndWait:^{
for (NSEntityDescription *entity in managedObjectModel) {
NSFetchRequest *fetchRequest = [NSFetchRequest new];
[fetchRequest setEntity:entity];
[fetchRequest setIncludesSubentities:NO];
NSArray *objects = [managedObjectContext executeFetchRequest:fetchRequest error:nil];
for (NSManagedObject *managedObject in objects) {
[managedObjectContext deleteObject:managedObject];
}
}


[managedObjectContext save:nil];
}];
}];
[operation setCompletionBlock:^{
// Do stuff once the truncation is complete
}];
[operation start];
}

这个实现利用NSOperation来执行主线程的删除,并在完成时通知。您可能希望在完成块中发出通知或其他内容,以便将状态冒泡回主线程。

如果需要删除所有对象且不删除备份文件,可以使用以下方法:

- (void)deleteAllObjectsInContext:(NSManagedObjectContext *)context
usingModel:(NSManagedObjectModel *)model
{
NSArray *entities = model.entities;
for (NSEntityDescription *entityDescription in entities) {
[self deleteAllObjectsWithEntityName:entityDescription.name
inContext:context];
}
}


- (void)deleteAllObjectsWithEntityName:(NSString *)entityName
inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *fetchRequest =
[NSFetchRequest fetchRequestWithEntityName:entityName];
fetchRequest.includesPropertyValues = NO;
fetchRequest.includesSubentities = NO;


NSError *error;
NSArray *items = [context executeFetchRequest:fetchRequest error:&error];


for (NSManagedObject *managedObject in items) {
[context deleteObject:managedObject];
NSLog(@"Deleted %@", entityName);
}
}

注意它可能非常慢(取决于对象图中有多少对象)。

这里是清洗核心数据的组合解决方案。

- (void)deleteAllObjectsInCoreData
{
NSArray *allEntities = self.managedObjectModel.entities;
for (NSEntityDescription *entityDescription in allEntities)
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entityDescription];


fetchRequest.includesPropertyValues = NO;
fetchRequest.includesSubentities = NO;


NSError *error;
NSArray *items = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];


if (error) {
NSLog(@"Error requesting items from Core Data: %@", [error localizedDescription]);
}


for (NSManagedObject *managedObject in items) {
[self.managedObjectContext deleteObject:managedObject];
}


if (![self.managedObjectContext save:&error]) {
NSLog(@"Error deleting %@ - error:%@", entityDescription, [error localizedDescription]);
}
}
}

[对请求更新回复的赏金的响应延迟]

回顾之前的答案,

  • 正如@Grouchal和其他人所建议的那样,获取和删除所有项仍然是一种有效和有用的解决方案。如果你有非常大的数据存储,那么它可能会很慢,但它仍然工作得很好。
  • 正如您和@groundhog注意到的那样,简单地删除数据存储将不再有效。即使你不使用外部二进制存储已经过时了,因为iOS 7使用WAL模式进行SQLite日志记录。在WAL模式下,任何Core Data持久存储都可能存在(可能很大的)日志文件。

但是有一种不同的、类似的方法可以移除持久存储。关键是将持久存储文件放在它自己的子目录中,该子目录不包含任何其他内容。不要只是把它放在documents目录(或任何地方)中,而是为持久存储创建一个新的子目录。该目录的内容最终将是持久存储文件、日志文件和外部二进制文件。如果您希望销毁整个数据存储,请删除该目录,它们将全部消失。

在设置持久化存储时,你会这样做:

NSURL *storeDirectoryURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"persistent-store"];
if ([[NSFileManager defaultManager] createDirectoryAtURL:storeDirectoryURL
withIntermediateDirectories:NO
attributes:nil
error:nil]) {
NSURL *storeURL = [storeDirectoryURL URLByAppendingPathComponent:@"MyApp.sqlite"];
// continue with storeURL as usual...
}

然后当你想把商店搬走的时候,

[[NSFileManager defaultManager] removeItemAtURL:storeDirectoryURL error:nil];

这将递归地删除自定义子目录和其中的所有Core Data文件。

这只在您没有将持久存储与其他重要数据放在同一个文件夹中时才有效。比如documents目录,其中可能有其他有用的东西。如果这是你的情况,你可以通过寻找你想要保留的文件并删除其他所有文件来获得相同的效果。喜欢的东西:

NSString *docsDirectoryPath = [[self applicationDocumentsDirectory] path];
NSArray *docsDirectoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:docsDirectoryPath error:nil];
for (NSString *docsDirectoryItem in docsDirectoryContents) {
// Look at docsDirectoryItem. If it's something you want to keep, do nothing.
// If it's something you don't recognize, remove it.
}

这种方法可能容易出错。你必须绝对确定你知道你想要保留的每一个文件,否则你可能会删除重要的数据。另一方面,您可以删除外部二进制文件,而不需要知道用于存储它们的文件/目录名称。

迅速的解决方案:

class func deleteAllManagedObjects() {


let modelURL = NSBundle.mainBundle().URLForResource("some string", withExtension: "mom")
let mom = NSManagedObjectModel(contentsOfURL: modelURL)


for entityName in mom.entitiesByName.keys {
let fr = NSFetchRequest(entityName: entityName as String)
let a = Utility.managedObjectContext().executeFetchRequest(fr, error: nil) as [NSManagedObject]
for mo in a {
Utility.managedObjectContext().deleteObject(mo)
}
}


Utility.managedObjectContext().save(nil)
}

iOS 10+的更新解决方案

使用NSBatchDeleteRequest删除实体中的所有对象,而不必将它们加载到内存中或遍历它们。

// create the delete request for the specified entity
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = MyEntity.fetchRequest()
let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)


// get reference to the persistent container
let persistentContainer = (UIApplication.shared.delegate as! AppDelegate).persistentContainer


// perform the delete
do {
try persistentContainer.viewContext.execute(deleteRequest)
} catch {
print(error.localizedDescription)
}

此代码已更新为iOS 10和Swift 3。如果你需要支持iOS 9,请参见这个问题

来源:

假设你正在使用MagicalRecord并且有一个默认的持久化存储:

我不喜欢所有假设存在特定文件和/或要求输入实体名称或类的解决方案。这是一个Swift(2),安全的方式删除所有实体的所有数据。删除后,它将重新创建一个新的堆栈(我实际上不确定这部分是多么必要)。

这是godo的“注销”风格的情况下,当你想删除一切,但有一个工作的存储和moc,以获得新的数据(一旦用户登录…)

extension NSManagedObject {


class func dropAllData() {


MagicalRecord.saveWithBlock({ context in


for name in NSManagedObjectModel.MR_defaultManagedObjectModel().entitiesByName.keys {
do { try self.deleteAll(name, context: context) }
catch { print("⚠️ ✏️ Error when deleting \(name): \(error)") }
}


}) { done, err in
MagicalRecord.cleanUp()
MagicalRecord.setupCoreDataStackWithStoreNamed("myStoreName")
}
}


private class func deleteAll(name: String, context ctx: NSManagedObjectContext) throws {
let all = NSFetchRequest(entityName: name)
all.includesPropertyValues = false


let allObjs = try ctx.executeFetchRequest(all)
for obj in allObjs {
obj.MR_deleteEntityInContext(ctx)
}


}
}

使用这个

+(NSArray *)fetchDataFromEntity:(NSString *)entityName context:(NSManagedObjectContext *)context
{
NSFetchRequest * fetchRequest =[[NSFetchRequest alloc] init];
NSEntityDescription * CategoriesEntity = [NSEntityDescription entityForName:entityName inManagedObjectContext:context];
[fetchRequest setEntity:CategoriesEntity];


NSError * error;
NSInteger count = [context countForFetchRequest:fetchRequest error:&error];


if (count && count>0) {


NSArray * fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects && fetchedObjects.count>0) {


return fetchedObjects;
}else
return nil;


}
else
return nil;
}
+ (void)deleteObjectsOfArray:(NSMutableArray*)ary context:(NSManagedObjectContext *)context {
for (NSManagedObject * obj in ary) {
[context deleteObject:obj];
}
NSError *saveError = nil;
[context save:&saveError];
}
+ (void)deleteEntity:(NSString *)entityName context:(NSManagedObjectContext *)context {
NSArray *listArray = [self fetchDataFromEntity:entityName context:context];
[self deleteObjectsOfArray:[NSMutableArray arrayWithArray:listArray] context:context];
}

我采取了Grouchal的代码,为了加快速度,我使用了并发模式的枚举(NSEnumerationConcurrent),它比for循环快了一点(在我的应用程序中,我为测试人员添加了这个功能,以便他们可以清除数据和做测试用例,而不是删除和安装应用程序)

- (void)resetObjects
{
[self deleteAllObjectsInEntity:@"Entity1"];
[self deleteAllObjectsInEntity:@"Entity2"];
[self deleteAllObjectsInEntity:@"Entity3"];
[self deleteAllObjectsInEntity:@"Entity4"];
}


-(void) deleteAllObjectsInEntity:(NSString*) entityName
{
MainDataContext *coreDataContext = [MainDataContext sharedInstance];
NSManagedObjectContext *currentContext = coreDataContext.managedObjectContext;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:currentContext];
[fetchRequest setEntity:entity];


NSError *error;
NSArray *items = [currentContext executeFetchRequest:fetchRequest error:&error];


[items enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSManagedObject * obj, NSUInteger idx, BOOL *stop) {
[currentContext deleteObject:obj];
}];




if (![currentContext save:&error]) {
NSLog(@"Error deleting %@ - error:%@",entityName,error);
}
}

iOS9+, Swift 2

删除所有实体中的所有对象

func clearCoreDataStore() {
let entities = managedObjectModel.entities
for entity in entities {
let fetchRequest = NSFetchRequest(entityName: entity.name!)
let deleteReqest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
do {
try context.executeRequest(deleteReqest)
} catch {
print(error)
}
}
}

iOS 10 + Swift 3解决方案:

func clearCoreDataStore() {
let delegate = UIApplication.shared.delegate as! AppDelegate
let context = delegate.persistentContainer.viewContext


for i in 0...delegate.persistentContainer.managedObjectModel.entities.count-1 {
let entity = delegate.persistentContainer.managedObjectModel.entities[i]


do {
let query = NSFetchRequest<NSFetchRequestResult>(entityName: entity.name!)
let deleterequest = NSBatchDeleteRequest(fetchRequest: query)
try context.execute(deleterequest)
try context.save()


} catch let error as NSError {
print("Error: \(error.localizedDescription)")
abort()
}
}
}

遍历所有核心数据实体并清除它们

这里我的swift3版本删除所有记录。'Users'是实体名称

@IBAction func btnDelAll_touchupinside(_ sender: Any) {


let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedObjectContext = appDelegate.persistentContainer.viewContext


let fetchReq = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")
let req = NSBatchDeleteRequest(fetchRequest: fetchReq)


do {
try managedObjectContext.execute(req)


} catch {
// Error Handling
}
}

适用于所有版本。传递实体名称并遍历删除所有条目并保存上下文。

func deleteData(entityToFetch: String, completion: @escaping(_ returned: Bool) ->()) {
var context = NSManagedObjectContext()
if #available(iOS 10.0, *) {
context = self.persistentContainer.viewContext
} else {
context = self.managedObjectContext
}


let fetchRequest = NSFetchRequest<NSFetchRequestResult>()
fetchRequest.entity = NSEntityDescription.entity(forEntityName: entityToFetch, in: context)
fetchRequest.includesPropertyValues = false
do {
let results = try context.fetch(fetchRequest) as! [NSManagedObject]
for result in results {
context.delete(result)
}
try context.save()
completion(true)
} catch {
completion(false)
print("fetch error -\(error.localizedDescription)")
}
}

iOS 10和Swift 3

假设您的实体名称是“Photo”,并且您创建了一个CoreDataStack类…

 func clearData() {
do {
let context = CoreDataStack.sharedInstance.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Photo")
do {
let objects  = try context.fetch(fetchRequest) as? [NSManagedObject]
_ = objects.map{$0.map{context.delete($0)}}
CoreDataStack.sharedInstance.saveContext()
} catch let error {
print("ERROR DELETING : \(error)")
}
}
}
这是一个很好的教程,教你如何使用CoreData以及如何使用这个方法。 https://medium.com/compileswift/parsing-json-response-and-save-it-in-coredata-step-by-step-fb58fc6ce16f#.1tu6kt8qb < / p >

下面这个版本可以删除每个表中的每条记录。

斯威夫特4

static func resetDatabase() {
do {
try dataStore.persistentStoreCoordinator.managedObjectModel.entities.forEach { (entity) in
if let name = entity.name {
let fetch = NSFetchRequest<NSFetchRequestResult>(entityName: name)
let request = NSBatchDeleteRequest(fetchRequest: fetch)
try mainContext.execute(request)
}
}


try mainContext.save()
} catch {
print("error resenting the database: \(error.localizedDescription)")
}
}

我经常使用的另一种方法(除了删除批处理请求)(基于应用程序需求)是重置持久存储。iOS 10+和Swift的实现如下所示(假设你有一个CoreDataManager类):

let persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "<Data-Model-Name>“)
container.loadPersistentStores(completionHandler: { (storeDescription, err) in
if let err = err {
fatalError("loading of store failed: \(err)")
}
})
return container
}()


func resetPersistentStore() {


if let persistentStore = persistentContainer.persistentStoreCoordinator.persistentStores.last {
let storeURL = persistentContainer.persistentStoreCoordinator.url(for: persistentStore)


do {
try persistentContainer.persistentStoreCoordinator.destroyPersistentStore(at: storeURL, ofType: NSSQLiteStoreType, options: nil)
} catch {
print("failed to destroy persistent store:", error.localizedDescription)
}


do {
try persistentContainer.persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeURL, options: nil)
} catch {
print("failed to re-add persistent store:", error.localizedDescription)
}
}


}

这种方法的一个优点是,它更直接,特别是当您在核心数据中有大量实体的数据记录时。在这种情况下,删除批处理请求将占用大量内存。

Swift 5.1解决方案

public static func reset() {
let coordinator = _persistentContainer.persistentStoreCoordinator
for store in coordinator.persistentStores where store.url != nil {
try? coordinator.remove(store)
try? FileManager.default.removeItem(atPath: store.url!.path)
}
}

Swift 4/5, iOS 9+

重建整个CoreData SQLite文件将确保所有数据都被擦除,因此所有实体都被删除。只需调用deleteAndRebuild()

class CoreDataStack {
// Change this
static let datamodelName = "ProjectName"
static let storeType = "sqlite"


static let persistentContainer = NSPersistentContainer(name: datamodelName)
private static let url: URL = {
let url = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0].appendingPathComponent("\(datamodelName).\(storeType)")


assert(FileManager.default.fileExists(atPath: url.path))


return url
}()


static func loadStores() {
persistentContainer.loadPersistentStores(completionHandler: { (nsPersistentStoreDescription, error) in
if let error = error {
fatalError(error.localizedDescription)
}
})
}


static func deleteAndRebuild() {
try! persistentContainer.persistentStoreCoordinator.destroyPersistentStore(at: url, ofType: storeType, options: nil)


loadStores()
}
}

似乎有两种方法:

假设您的核心数据堆栈有一个典型的单例。

import CoreData
public let core = Core.shared
public final class Core {
static let shared = Core()
var container: NSPersistentContainer!
private init() {
container = NSPersistentContainer(name: "stuff")
//deleteSql()
container.loadPersistentStores { storeDescription, error in
if let error = error { print("Error loading... \(error)") }
}
//deleteAll()
}
    

func saveContext() { // typical save helper
if container.viewContext.hasChanges {
do { try container.viewContext.save()
} catch { print("Error saving... \(error)") }
}
}
    

然后……

    func deleteSql() {
let url = FileManager.default.urls(
for: .applicationSupportDirectory,
in: .userDomainMask)[0].appendingPathComponent( "stuff.sqlite" )
        

guard FileManager.default.fileExists(atPath: url.path) else {
print("nothing to delete!")
return
}
        

do {
try container.persistentStoreCoordinator.destroyPersistentStore(
at: url, ofType: "sqlite", options: nil)
print("totally scorched the sql file. you DO now have to LOAD again")
}
catch {
print("there was no sql file there!")
}
}
    

func deleteAll() { // courtesy @Politta
for e in container.persistentStoreCoordinator.managedObjectModel.entities {
let r = NSBatchDeleteRequest(
fetchRequest: NSFetchRequest(entityName: e.name ?? ""))
let _ = try? container.viewContext.execute(r)
}
saveContext()
print("conventionally deleted everything from within core data. carry on")
}
}

1. 焦化SQL文件

感谢优秀的@J。能源部的答案。您完全销毁了sql文件。

必须做这个

  • 在加载核心数据之前,即在创建容器之后,但是
  • 在真正载入商店之前。)

(请注意示例代码"//deleteSql()"就在初始化之前。)

2. 逐个删除核心数据中的所有内容

感谢精彩的@Politta回答。一旦core data启动并运行,就可以随时执行此操作。

(请注意示例代码"//deleteAll()"是在初始化之后。)

方法一在开发过程中可能更有用。方法二在生产中可能更有用(在相对不常见的情况下,由于某种原因需要擦除所有内容)。