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


Edit

我希望以编程方式做到这一点,这样用户就可以基本上按下重置按钮。


当前回答

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

}

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

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

其他回答

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

您仍然可以使用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

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

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

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

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

我写了一个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。