245

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


编辑

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

4

33 回答 33

202

您仍然可以使用 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),仅仅删除 storeURLs 指向的文件是不够的。您将留下外部记录文件。由于这些外部记录文件的命名方案是不公开的,所以我还没有一个通用的解决方案。– an0 2012 年 5 月 8 日 23:00

于 2009-08-03T12:42:28.267 回答
141

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

}

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

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

于 2009-07-03T08:12:23.850 回答
69

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,请参阅此问题

资料来源:

于 2015-08-12T09:34:06.863 回答
40

我编写了一个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类中,该类负责(除其他外)在它为 nil 时创建 persistentStore。

于 2010-06-10T05:30:40.370 回答
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;
于 2011-12-05T19:19:26.887 回答
20

iOS9+,斯威夫特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)
        }
    }
}
于 2016-05-20T13:55:06.740 回答
19

MagicalRecord使这变得非常容易。

[MyCoreDataObject MR_truncateAll];
于 2011-04-05T14:50:43.707 回答
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];

这会递归地删除自定义子目录和其中的所有核心数据文件。

这仅在您尚未将持久存储与其他重要数据放在同一文件夹中时才有效。就像文档目录一样,里面可能还有其他有用的东西。如果这是您的情况,您可以通过查找您想要保留的文件并删除其他所有文件来获得相同的效果。就像是:

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

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

于 2013-12-05T21:12:06.197 回答
11

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

- (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]);
        }
    }  
}
于 2013-10-10T09:06:44.980 回答
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);
    }
}

请注意,它可能会非常慢(取决于对象图中的对象数量)。

于 2013-02-22T17:48:41.903 回答
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执行主线程的删除并在完成时通知。您可能希望在完成块中发出通知或其他内容,以将状态冒泡回主线程。

于 2012-12-20T22:51:25.290 回答
6

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

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

于 2016-09-26T06:18:18.530 回答
5

斯威夫特 4/5,iOS 9+

重建整个CoreDataSQLite 文件将确保删除所有数据,因此删除所有实体。只要打电话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()
    }
}
于 2019-10-12T10:42:56.973 回答
4

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

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

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

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

然后用于managedObjectContext访问数据库(现在应该是空的),不知何故数据仍然存在。经过一段时间的排查,我发现在使用访问数据库之前,我需要重新设置managedObjectContextmanagedObjectmanagedObjectModel和 。现在我有一个干净的数据库可以写入。 persistentStoreCoordinatormanagedObjectContext

于 2011-12-12T21:50:17.230 回答
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];
}
于 2012-11-08T17:13:43.180 回答
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)
    }
于 2014-09-06T08:18:30.063 回答
3

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

if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
// do something with the error
}
于 2011-09-29T09:43:52.543 回答
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];
}
于 2012-08-05T00:19:27.277 回答
3

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

斯威夫特 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)")
    }
}
于 2018-03-07T03:27:11.237 回答
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" 将返回所有实体名称。最后,别忘了保存。

于 2012-12-07T06:40:02.183 回答
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];
于 2015-01-28T13:44:19.563 回答
2

斯威夫特 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)
    }
}
于 2019-10-12T06:16:48.063 回答
1

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

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)")
    }
}
于 2017-03-02T12:19:39.063 回答
1

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

}

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

于 2019-07-02T04:26:33.440 回答
1

似乎有两种方法:

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

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()”是在初始化之后。)

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

于 2020-02-03T13:46:48.783 回答
0

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

于 2009-07-03T05:09:26.940 回答
0

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

于 2009-07-03T11:56:15.160 回答
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)
        }

    }
}
于 2015-11-08T16:20:41.490 回答
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];
}
于 2016-02-16T06:46:33.703 回答
0

NSEnumerationConcurrent我采用了Grouchal 的代码并加快了速度,我使用了并发模式(安装软件)

- (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);
    }
}
于 2016-03-04T13:19:37.237 回答
0

这是我的 swift3 版本,用于删除所有记录。“用户”是实体名称

@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
    }   
}
于 2017-02-25T14:30:19.840 回答
0

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

于 2017-03-15T05:16:18.300 回答
-8

你们都让这看起来很复杂。你可以发送你的 NSManagedObjectContext 重置方法

于 2012-03-12T01:29:10.083 回答