我在不需要保存用户数据的iOS 7+应用中使用Core Data
,应用程序所需的所有数据都会被请求服务,并且可以随时恢复。因此,如果我在下一个应用程序更新中更改我的数据模型,那么删除所有以前的数据并再次请求所有数据都没有问题。但我不知道如何简单地用新的数据模型替换以前的数据模型,而不执行迁移,因为它看起来我不需要这样做......
提前致谢
答案 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-shm
和cd.sqlite-wal
。
Core Data的WAL日记模式在iOS 7和OSX Mavericks中被默认引入,正如Apple在QA1809报道的那样。
案例2:使用内存商店
根据建议,您可以使用NSInMemoryStoreType
而不是NSSQLiteStoreType
切换到内存存储。在这种情况下,擦除商店要容易得多:所有数据都驻留在内存中,当应用程序停止运行时,所有数据都会消失,磁盘上没有任何数据可供您清理。下次,您可能会加载完全不同的模型,而不进行任何迁移,因为没有要迁移的数据
但是,这个实现的解决方案不允许您在会话之间缓存数据,这看起来像是您希望在应用更新之间做的事情(即,只有在应用更新时才能删除商店和模型改变,否则将它保存在磁盘上会很有用。)
注意:强>
这两种方法都是可行的,有利有弊,我相信也可能有其他策略。最后,您应该拥有所有元素来决定在特定情况下最佳方法。
答案 1 :(得分:2)
答案 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
调用一次:)