无法销毁使用 Core Data 和 SQLite 创建的持久存储

Chu*_*ger 0 core-data ios swift

我有一个 iOS 应用程序,我想在每次启动时从一个新的 Core Data 数据库开始。存储类型是 SQLite。

但是,当我调用 persistentStoreCoordinator.destroyPersistentStore() 时,我 100% 都会收到错误消息。

这是代码:

func destroyPersistentStore() {
    guard let modelURL = Bundle.main.url(forResource: self.modelName, withExtension: "momd") else {
        print("Missing data model - could not destroy")
        return
    }

    do {
        try persistentStoreCoordinator.destroyPersistentStore(at: modelURL, ofType: storeType, options: nil)
    } catch  {
        print("Unable to destroy persistent store: \(error) - \(error.localizedDescription)")
   }
}
Run Code Online (Sandbox Code Playgroud)

错误是:

无法销毁持久存储:Error Domain=NSSQLiteErrorDomain Code=14 "(null)" UserInfo={NSFilePath=.../AppName.app/ModelName.momd, reason=Failed to truncate database} - 操作无法完成. (NSSQLiteErrorDomain 错误 14。)

即使发生此错误,该应用程序仍可以保存和访问商店中的数据。问题在于每次启动时都会加载初始数据,从而产生重复数据。

下面是调用 destroyPersistentStore 时的情况:

  1. SQLite 数据文件肯定存在并且包含数据
  2. 发生在模拟器或真机上
  3. modelUrl 是正确的,指向妈妈
  4. 存储类型是 SQLite
  5. SQLite 数据文件保存在 Documents 目录中
  6. persistentStoreCoordinator.url(for: persistentStoreCoordinator.persistentStores.first!) 指向 Documents 目录中的文件。

我在网上搜索了答案,但找不到任何报告此错误的人,但我在此项目和简化的演示项目中都有错误。我根本无法让 destroyPersistentStore 工作。

最后,当我暂停执行并调用persistentStoreCoordinator.managedObjectModel时,第一行是:

po persistentStoreCoordinator.managedObjectModel() isEditable 0, 实体...

isEditable 问题可能是问题吗?我将如何改变它?

Tim*_*Tim 5

您将 Core Data 堆栈中的两个对象混为一谈:

  • 模型位于您的应用程序包内,具有扩展名.momd,并包含有关您的 Core Data 对象定义的信息:您拥有哪些实体、它们具有哪些属性、它们之间的关系等等。
  • 持久性存储在应用程式的容器(未在包)的数据文件。您在创建或加载持久存储时定义其 URL。它包含模型对象实际实例的数据,而不是抽象定义。

我认为您想获取持久存储的 URL,而不是获取模型的 URL。您可以通过查看持久存储协调器的persistentStores数组,选择一个并获取其 URL来做到这一点:

func destroyPersistentStore() {
    guard let firstStoreURL = persistentStoreCoordinator.persistentStores.first?.url else {
        print("Missing first store URL - could not destroy")
        return
    }

    do {
        try persistentStoreCoordinator.destroyPersistentStore(at: firstStoreURL, ofType: storeType, options: nil)
    } catch  {
        print("Unable to destroy persistent store: \(error) - \(error.localizedDescription)")
   }
}
Run Code Online (Sandbox Code Playgroud)

这将破坏第一家商店;如果您有多个,则可以根据您的应用程序的要求,遍历持久存储将它们全部销毁。