【问题标题】:How to resolve: "NSPersistentStoreCoordinator has no persistent stores"?如何解决:“NSPersistentStoreCoordinator 没有持久存储”?
【发布时间】:2015-10-25 16:32:04
【问题描述】:

我完全按照本教程进行操作,它将 CoreData 添加到现有应用程序中: https://www.youtube.com/watch?v=WcQkBYu86h8

当我到达 seedPerson() moc.save() 时,应用程序崩溃并出现以下错误:

CoreData: 错误: 非法尝试保存到从未使用过的文件 打开。 “这个 NSPersistentStoreCoordinator 没有持久存储 (未知)。它无法执行保存操作。”。没有最后一个错误 记录下来。

已添加 NSManagedSubclass。

DataController 已连接好,我可以进入它。直到 save() 出现问题。知道我可能遗漏了什么导致此错误吗?

【问题讨论】:

  • 也许你没有给addPersistentStoreWithType:configuration:URL:options:error:打电话?您必须先添加一个持久存储,然后才能将数据保存到其中。
  • 发布创建核心数据堆栈的代码。
  • 你修好了吗?

标签: core-data swift2 xcode7


【解决方案1】:

我也遵循了那个 YouTube 教程并遇到了同样的问题。我刚刚删除了添加持久存储的后台线程块并且它工作了。这是我的DataController

import UIKit
import CoreData

class WellbetDataController: NSObject {
    var managedObjectContext: NSManagedObjectContext

    override init() {
        // This resource is the same name as your xcdatamodeld contained in your project.
        guard let modelURL = NSBundle.mainBundle().URLForResource("DataModel", withExtension:"momd") else {
            fatalError("Error loading model from bundle")
        }

        // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
        guard let mom = NSManagedObjectModel(contentsOfURL: modelURL) else {
            fatalError("Error initializing mom from: \(modelURL)")
        }

        let psc = NSPersistentStoreCoordinator(managedObjectModel: mom)
        self.managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
        self.managedObjectContext.persistentStoreCoordinator = psc

        let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
        let docURL = urls[urls.endIndex-1]
        /* The directory the application uses to store the Core Data store file.
        This code uses a file named "DataModel.sqlite" in the application's documents directory.
        */
        let storeURL = docURL.URLByAppendingPathComponent("DataModel.sqlite")
        do {
            try psc.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil)
        } catch {
            fatalError("Error migrating store: \(error)")
        }



//        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
//            let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
//            let docURL = urls[urls.endIndex-1]
//            /* The directory the application uses to store the Core Data store file.
//            This code uses a file named "DataModel.sqlite" in the application's documents directory.
//            */
//            let storeURL = docURL.URLByAppendingPathComponent("DataModel.sqlite")
//            do {
//                try psc.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil)
//            } catch {
//                fatalError("Error migrating store: \(error)")
//            }
//        }
    }
}

【讨论】:

  • 谢谢!遇到同样的问题 - 删除 dispatch_async 修复它。
  • 我使用书中的一些示例代码遇到了类似的问题。我试图在应用程序开始时设置一些初始托管对象以进行测试。将此操作移回主线程意味着 NSPersistentStoreCoordinator 设置在其他任何东西有机会尝试将数据写入 NSManagedObjectContext 之前完成。就我而言,我想我是在异步操作中完成设置工作之前尝试写入 NSManagedObjectContext。
【解决方案2】:

不幸的是,该视频使用了 Apple 网站上的一些代码,而该代码示例存在缺陷。主要缺陷是它在将持久存储添加到 MOC 之前缓存 MOC。因此,如果存储的创建完全失败,托管对象上下文将使用没有存储的持久存储协调器进行初始化。

您需要使用调试器并逐步执行创建 PSC 的代码(DataController.init 方法)并查看失败的原因。如果您以与该示例相同的方式剪切/粘贴,那么您可能在实例化模型时也忘记更改模型的名称。

无论如何,最可能的原因是该函数中的某些初始化代码失败,您随后可以愉快地使用没有存储的核心数据堆栈。

【讨论】:

    【解决方案3】:

    您需要加载持久存储

    let persistentContainer = NSPersistentContainer(name: "DbName") 
    persistentContainer.loadPersistentStores() { [weak self] _, error in      
          self?.persistentContainer.viewContext.automaticallyMergesChangesFromParent = true            
    }
    

    【讨论】:

    • 这仅适用于 iOS 10+。
    【解决方案4】:

    问题出在这两行:

    guard let modelURL = NSBundle.mainBundle().URLForResource("DataModel", withExtension:"momd") else {
    

    &&

    let storeURL = docURL.URLByAppendingPathComponent("DataModel.sqlite")
    

    如果您的 CoreData 是由 Xcode 自动创建的,则需要将DataModel 更改为您的应用程序的名称。在 AppDelegate.swift 中查找这些行

    【讨论】:

      【解决方案5】:

      如果这是您在将核心数据放入其中后第一次运行该应用程序,那么可以通过从模拟器中删除该应用程序并再次运行它来工作。

      这件事发生在我身上,在我这样做之后它就起作用了。

      【讨论】:

        猜你喜欢
        • 2013-10-31
        • 1970-01-01
        • 2013-04-08
        • 1970-01-01
        • 2013-03-07
        • 2016-02-04
        • 2020-05-30
        • 2012-08-18
        • 1970-01-01
        相关资源
        最近更新 更多