【问题标题】:NSUnderlyingException = "Can't add the same store twice" when migrating core dataNSUnderlyingException = 迁移核心数据时“不能两次添加同一个商店”
【发布时间】:2018-01-14 20:51:03
【问题描述】:

我正在使用以下代码设置我的应用持久化容器:

lazy var persistentContainer: NSPersistentContainer = {
    let container = NSPersistentContainer(name: "App_Name")

    let myFileManager = FileManager()

    do {
        let docsurl = try myFileManager.url(for:.applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: false)

        let myUrl = docsurl.appendingPathComponent("App_Name")

        let description = NSPersistentStoreDescription(url: myUrl)
        container.persistentStoreDescriptions = [description]

        let options = [NSInferMappingModelAutomaticallyOption : true,
                        NSMigratePersistentStoresAutomaticallyOption : true]

        try container.persistentStoreCoordinator.addPersistentStore(ofType: NSInMemoryStoreType, configurationName: nil, at: myUrl, options: options)

    } catch {
        fatalErrorText = error.localizedDescription
        print(fatalErrorText)
    }

    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error as NSError? {
            fatalErrorText = error.debugDescription
            print(fatalErrorText)
        }
    })
    return container
}()

但是,当我尝试访问核心数据时,出现以下错误:

2017-08-07 14:43:57.391529+0100 应用名称[98764:1854740] [错误] 错误:-addPersistentStoreWithType:SQLite 配置:(null) URL:file:///Users/Seb/Library/Developer /CoreSimulator/Devices/241E1A36-631B-4071-8357-5F551F32403F/data/Containers/Data/Application/BC35D1CD-FA17-4F1F-99A0-EB0E73A42F3C/Library/Application%20Support/App_Name.sqlite 选项:{ NSInferMappingModelAutomaticallyOption = 1; NSMigratePersistentStoresAutomaticallyOption = 1; } ... 返回错误 Error Domain=NSCocoaErrorDomain Code=134080 "(null)" UserInfo={NSUnderlyingException=Can't add the same store two times} with userInfo dictionary { NSUnderlyingException = "不能两次添加同一个商店"; } CoreData:错误:-addPersistentStoreWithType:SQLite 配置:(null) URL:file:///Users/Seb/Library/Developer/CoreSimulator/Devices/241E1A36-631B-4071-8357-5F551F32403F/data/Containers/Data/Application/ BC35D1CD-FA17-4F1F-99A0-EB0E73A42F3C/Library/Application%20Support/App_Name.sqlite 选项:{ NSInferMappingModelAutomaticallyOption = 1; NSMigratePersistentStoresAutomaticallyOption = 1; } ... 返回错误 错误域=NSCocoaErrorDomain Code=134080 "(null)" UserInfo={NSUnderlyingException=不能两次添加同一个商店} 与 userInfo 字典 { NSUnderlyingException = "不能两次添加同一个商店"; }

我已启用 iCloud,并且确实找到了声称问题出在 iCloud 的答案,但他们的解决方案对我不起作用。

我在这里找到了解决此问题的其他一些解决方案,但无法破译/翻译答案。

【问题讨论】:

  • 错误信息不能添加同一个商店两次很清楚。您正在混淆 pre-iOS10 (addPersistentStore) 和 iOS10 代码 (loadPersistentStores()),这会导致两次添加持久存储。仅使用其中一种模式来设置核心数据堆栈
  • @vadian 啊,好吧 - 所以如果我删除两者中的一个,一切都会好的。我应该保留哪一个?还是没关系?
  • 这很重要,如果您保留addPersistentStore,您必须实现其他属性,以便更容易保留loadPersistentStores。删除myFileManager 行和整个do - catch 块。
  • @vadian - 那么它会使用迁移模型自动管理迁移吗?
  • 核心数据代码等同于核心数据栈。必须处理核心数据通信。在 Xcode 中创建一个新项目并选中 Core Data 复选框。 Xcode 将创建代码来为您创建 Core Data 堆栈。

标签: ios sqlite core-data swift3


【解决方案1】:

NSPersistentContainer 是核心数据堆栈所需的所有包装器。它将使用带有单个 sql 存储的 persistentStoreCoordinator 设置创建 managedObjectContext。使用您给它的名称查找模型并使用相同名称命名 sql 文件很简单。 NSPersistentContainer 的自动迁移默认开启。

如果您需要更多自定义设置,您可以自己创建所有实体(这并不难)。或者您可以在调用loadPersistentStores 之前设置persistentStoreDescriptions 属性。使用 persistentStoreDescription,您可以设置将 sql 文件保存到的 URL,并设置 shouldMigrateStoreAutomatically。 通常没有理由这样做,因为它默认设置为 true,请参阅 https://developer.apple.com/documentation/coredata/nspersistentstoredescription/1640566-shouldmigratestoreautomatically

TL;DR 去掉 do catch 中的所有内容,loadPersistentStores 的默认行为将起作用 find

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-14
    • 2017-07-07
    • 1970-01-01
    • 2011-04-07
    • 2012-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多