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

时间:2009-07-03 04:55:29

标签: ios cocoa cocoa-touch core-data nsmanagedobject

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


修改

我希望以编程方式执行此操作,以便用户可以实际点击reset按钮。

33 个答案:

答案 0 :(得分:196)

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

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指向的文件是不够的。您将保留外部记录文件。由于这些外部记录文件的命名方案不公开,我还没有通用的解决方案。 - 2012年5月8日23:00

答案 1 :(得分:139)

您可以删除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);
    }

}

我选择逐桌进行的原因是它让我确认正在进行编程时删除表内容是明智的,并且没有我宁愿保留的数据。

执行此操作比删除文件要慢得多,如果此方法花费的时间过长,我将更改为文件删除。

答案 2 :(得分:54)

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 let error as NSError {
    print(error)
}

此代码已针对iOS 10和Swift 3进行了更新。如果您需要支持iOS 9,请参阅this question

来源:

答案 3 :(得分:37)

我编写了一个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类中,该类负责(除其他事项外)创建持久存储时它为零。

答案 4 :(得分:27)

我从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.persistentStoreCoordinator,我在Home View Controller中声明了一个属性。 (不要担心我用于保存和加载的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;

答案 5 :(得分:21)

MagicalRecord让这很容易。

[MyCoreDataObject MR_truncateAll];

答案 6 :(得分:16)

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)
        }
    }
}

答案 7 :(得分:13)

[回应赏金要求更新回复的迟回答]

查看之前的答案,

  • 根据@Grouchal和其他人的建议,提取和删除所有项目仍然是一种有效且有用的解决方案。如果你有非常大的数据存储,那么它可能会很慢,但它仍然可以正常工作。
  • 正如您和@groundhog所说,简单地删除数据存储不再有效。即使您不使用外部二进制存储,它也已过时,因为iOS 7使用WAL模式进行SQLite日记功能。使用WAL模式,可能存在(可能很大的)日志文件,用于任何Core Data持久性存储。

但是有一种不同的,类似的方法来删除有效的持久存储。关键是将持久性存储文件放在不包含任何其他内容的子目录中。不要只是将它粘贴在文档目录(或任何地方),只为持久存储创建一个新的子目录。该目录的内容最终将成为持久存储文件,日志文件和外部二进制文件。如果您想要整个数据存储,请删除该目录,它们将全部消失。

在设置持久存储时,您会执行以下操作:

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文件。

仅当您的持久性商店与其他重要数据在同一文件夹中时才有效。就像文档目录一样,它可能还有其他有用的东西。如果这是您的情况,您可以通过查找执行想要保留的文件并删除其他所有内容来获得相同的效果。类似的东西:

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.
}

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

答案 8 :(得分:10)

如果要删除所有对象而不想删除后备文件,可以使用以下方法:

- (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);
    }
}

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

答案 9 :(得分:10)

以下是清除核心数据的组合解决方案。

- (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]);
        }
    }  
}

答案 10 :(得分:6)

如果你想删除所有对象路由(这比拆除核心数据堆栈简单得多,但性能较差),这是一个更好的实现:

- (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执行主线程的删除并在完成时通知。您可能希望在完成块中发出通知或某些内容,以将状态冒泡回主线程。

答案 11 :(得分:5)

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()
        }
    }
}

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

答案 12 :(得分:4)

这是一个稍微简化的版本,对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];
}

答案 13 :(得分:4)

快速解决方案:

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)
    }

答案 14 :(得分:3)

这个问题有几个很好的答案。这是一个很简洁的一个。前两行删除了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];
}

答案 15 :(得分:3)

作为在其他地方保存搜索的快速参考 - 删除后重新创建持久存储可以通过以下方式完成:

if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
// do something with the error
}

答案 16 :(得分:3)

感谢您的帖子。我跟着它,它对我有用。但我有另一个问题,在任何回复中都没有提到。所以我不确定这是不是我。

无论如何,我想我会在这里发布问题以及解决问题的方法。

我在数据库中有一些记录,我想在将新数据写入数据库之前清除所有内容,所以我做了所有事情,包括

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

然后使用managedObjectContext访问数据库(现在应该是空的),不知怎的,数据仍然存在。 经过一段时间的问题排查后,我发现我需要重置managedObjectContextmanagedObjectmanagedObjectModelpersistentStoreCoordinator,在我使用managedObjectContext访问数据库之前。现在我有一个干净的数据库要写。

答案 17 :(得分:2)

您还可以找到所有实体名称,并按名称删除它们。它是一个更长的版本,但运行良好,这样你就不必使用持久性存储

 - (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”将返回所有实体名称。最后,别忘了保存。

答案 18 :(得分:2)

接受的答案是正确的,因为NSFileManager删除URL是正确的,但正如iOS 5+编辑中所述,持久性存储不仅仅由一个文件表示。对于SQLite存储它的* .sqlite,* .sqlite-shm和* .sqlite-wal ...幸运的是,因为iOS 7+我们可以使用方法

[NSPersistentStoreCoordinator +removeUbiquitousContentAndPersistentStoreAtURL:options:error:]

负责删除,所以代码应该是这样的:

NSPersistentStore *store = ...;
NSError *error;
NSURL *storeURL = store.URL;
NSString *storeName = ...;
NSPersistentStoreCoordinator *storeCoordinator = ...;
[storeCoordinator removePersistentStore:store error:&error];
[NSPersistentStoreCoordinator removeUbiquitousContentAndPersistentStoreAtURL:storeURL.path options:@{NSPersistentStoreUbiquitousContentNameKey: storeName} error:&error];

答案 19 :(得分:1)

这是一个删除每个表中每条记录的版本。

Swift 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)")
    }
}

答案 20 :(得分:0)

iOS 10和Swift 3

假设您的实体名称为&#34; Photo&#34;,并且您创建了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

答案 21 :(得分:0)

假设您正在使用MagicalRecord并拥有默认持久性存储:

我不喜欢假设某些文件存在和/或要求输入实体名称或类的所有解决方案。这是一种从所有实体中删除所有数据的Swift(2)安全方法。删除后它也会重新创建一个新的堆栈(我实际上不确定这部分是如何必要的)。

当你想要删除所有内容但是有一个工作存储和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)
        }

    }
}

答案 22 :(得分:0)

我经常使用的另一种方法(基于删除批处理请求)(基于应用程序要求)是重置持久性存储。 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)
        }
    }

}

此方法的一个优点是它更加简单明了,尤其是当您在核心数据中有大量实体的数据记录负载时。在这种情况下,删除批处理请求将占用大量内存。

答案 23 :(得分:0)

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)
    }
}

答案 24 :(得分:0)

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()
    }
}

答案 25 :(得分:0)

似乎有两种方法:

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

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.Doe优秀答案。您完全破坏了sql文件。

必须执行此操作

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

(注意示例代码行“ // deleteSql()”就在初始化之前。)

2。删除核心数据中的所有内容

由@Politta出色的答案提供。核心数据启动并运行后,您可以随时执行此操作。

(注意示例代码行“ // deleteAll()”在初始化之后。)

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

答案 26 :(得分:0)

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

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)")
    }
}

答案 27 :(得分:0)

这里我的swift3版本用于删除所有记录。 &#39;用户&#39;是实体名称

@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
    }   
}

答案 28 :(得分:0)

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

答案 29 :(得分:0)

我使用了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);
    }
}

答案 30 :(得分:0)

使用此

+(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];
}

答案 31 :(得分:0)

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

答案 32 :(得分:-8)

你们都让这看起来很复杂。您只需向NSManagedObjectContext发送重置方法

即可