【问题标题】:Crash on App launch because of insertion in Core Data ([NSManagedObjectContext insertObject:])由于插入核心数据([NSManagedObjectContext insertObject:]),应用程序启动时崩溃
【发布时间】:2021-09-10 00:43:25
【问题描述】:

在一些崩溃报告中观察到了这种崩溃,但没有直接得到它。我在 SO 上分析了很多类似的事情,但无法就问题得出结论。以下是崩溃日志中的几张图片:

class CoreDataProvider: NSObject, NSFetchedResultsControllerDelegate {
    static let sharedList: CoreDataProvider = CoreDataProvider()
    static let sharedDataManager: CoreDataManager = CoreDataManager()
    var isListObject: Bool = false

    var fetchedConversationResultsController: NSFetchedResultsController<NSFetchRequestResult>?

    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {

        if let object = anObject as? NSManagedObject, type == NSFetchedResultsChangeType.insert {
            if controller == fetchedConversationResultsController{
                CoreDataManager.sharedInstance.threadCoreBG.async { [weak self] in
                    **self?.fetchedConversationResultsController?.managedObjectContext.insert(object)**
                }
            }
        }
    }
}

基本上崩溃是在上面突出显示的行中指出的。 其中 threadCoreBG 是:

var threadCoreBG: DispatchQueue = DispatchQueue(label: "coreDataThread", qos: .background)

我怀疑一切都是可选的,如果是这种情况,它是如何插入 nil 对象的,或者我无法得出问题的结论。

【问题讨论】:

    标签: ios swift macos core-data


    【解决方案1】:

    NSManagedObjectContext 实例在内部管理自己的DispatchQueue,您无需创建自定义DispatchQueue 即可使用它。

    let context = fetchedConversationResultsController?.managedObjectContext
    context.perform { // This will use correct queue automatically
        context.insert(object)
    }
    

    【讨论】:

      【解决方案2】:

      使用DispatchQueue 不适合Core Data。不一致、难以重现的崩溃正是您使用它们时发生的情况。

      使用 Core Data,你需要在任何时候使用 performperformAndWait 来做任何涉及 Core Data 对象的事情。 DispatchQueue 是一个类似的概念,但在这种情况下不正确。

      唯一的例外是如果您的代码在主队列上运行并且您的托管对象上下文使用主队列并发(例如使用来自持久容器的viewContext)。然后你可以跳过performperformAndWait 如果你愿意。

      你应该:

      1. 重写您的DispatchQueue 代码,使其使用performperformAndWait
      2. 开启Core Data concurrency debugging 可帮助您找到需要在应用中进行类似更改的其他情况。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-01-18
        • 2018-07-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多