核心数据:如何删除和重建数据存储?

时间:2015-03-13 07:54:54

标签: ios core-data core-data-migration

我在不需要保存用户数据的iOS 7+应用中使用Core Data,应用程序所需的所有数据都会被请求服务,并且可以随时恢复。因此,如果我在下一个应用程序更新中更改我的数据模型,那么删除所有以前的数据并再次请求所有数据都没有问题。但我不知道如何简单地用新的数据模型替换以前的数据模型,而不执行迁移,因为它看起来我不需要这样做......

提前致谢

3 个答案:

答案 0 :(得分:12)

案例1:您正在使用SQLite商店

如果您的商店类型为NSSQLiteStoreType,则适用。即使你打算不时删除你的数据,坚持使用SQLite并不是一个坏主意,因为它可以让你灵活地将你的缓存数据保存在磁盘上,只要你愿意,只有在你改变你的时才删除它模型,您不希望应用任何迁移。

快速解决方案?在初始化Core Data时,在启动时删除NSPersistentStoreCoordinator的商店。 例如,如果您使用的是Apple的样板代码提供的默认SQLite存储:

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"cd.sqlite"]

您只需删除该文件:

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

然后像往常一样使用storeURL添加新的持久性商店 如果您有新型号,并且您不需要进行任何迁移,则NSPersistentStoreCoordinator不会抱怨,但您的数据当然会丢失。

不言而喻,当您检测到数据模型中的更改时,您可以决定使用此解决方案,如果没有更改,则可以单独保留存储,以便您可以在必要时保留缓存的数据。

<强>更新

正如 TomHerrington 在评论中所建议的,为了确保您已完全删除旧商店,您还应该删除日记文件,如果您将来可能会再次出现并困扰您不要照顾他们 如果您的商店文件名为cd.sqlite,如示例中所示,要删除的其他文件为cd.sqlite-shmcd.sqlite-wal

Core Data的WAL日记模式在iOS 7和OSX Mavericks中被默认引入,正如Apple在QA1809报道的那样。

案例2:使用内存商店

根据建议,您可以使用NSInMemoryStoreType而不是NSSQLiteStoreType切换到内存存储。在这种情况下,擦除商店要容易得多:所有数据都驻留在内存中,当应用程序停止运行时,所有数据都会消失,磁盘上没有任何数据可供您清理。下次,您可能会加载完全不同的模型,而不进行任何迁移,因为没有要迁移的数据 但是,这个实现的解决方案不允许您在会话之间缓存数据,这看起来像是您希望在应用更新之间做的事情(即,只有在应用更新时才能删除商店和模型改变,否则将它保存在磁盘上会很有用。)

注意:

这两种方法都是可行的,有利有弊,我相信也可能有其他策略。最后,您应该拥有所有元素来决定在特定情况下最佳方法。

答案 1 :(得分:2)

我认为destroyPersistentStoreAtURL的{​​{1}}方法就是你想要的。

它将删除数据存储和日志文件以及需要删除的所有其他内容。

请看 Apple documentation

答案 2 :(得分:1)

针对iOS 9或更高版本的工作Swift解决方案

共享的CoreData管理器:

class CoreDataContext {
    static let datamodelName = "CoreDataTests"
    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
            guard let error = error else {
                return
            }
            fatalError(error.localizedDescription)
        })
    }

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

        loadStores()
    }
}

仅在appDelegate中调用loadStores一次,而要删除并重建数据库时,则deleteAndRebuild调用一次:)