ios - 核心数据私有(private)上下文 performAndWait 导致调试崩溃

标签 ios swift core-data

我在调试核心数据并发问题时遇到了问题。

在我的方案中我启用了:

-com.apple.CoreData.Logging.stderr 1
-com.apple.CoreData.ConcurrencyDebug 1

我想在后台线程中从核心数据中获取记录。

所以在我的 UIViewController 中,我创建了 DispatchQueue.global(qos: .background).async,我在其中调用 Core Data 来获取记录。

我正在使用父/子:

    func performStationsFetch(filter: String = "") -> [Stations] {
    let privateMOC = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
    let parentMOC = (UIApplication.shared.delegate as! AppDelegate).managedObjectContext

    privateMOC.parent = parentMOC

    var fetchResults: [Stations] = []

    privateMOC.performAndWait {
        let fetchRequest: NSFetchRequest<Stations> = Stations.fetchRequest()
        fetchRequest.predicate = NSPredicate(format: "name contains[c] %@", filter)

        do {
            fetchResults = try privateMOC.fetch(fetchRequest)
        } catch {
            print("Fetch error")
        }
    }

    return fetchResults
}

问题是如果我调用 privateMOC.perform 代码工作正常。

但是如果我调用 privateMOC.performAndWait 代码崩溃并给我 +[NSManagedObjectContext __Multithreading_Violation_AllThatIsLeftToUsIsHonor__]

有没有人建议什么可能是问题?

最佳答案

当您尝试访问函数的结果时,就会发生多线程冲突。如果你使用 perform,结果是空的——所以没有问题。如果您使用 performAndWait,那么您返回的是几乎肯定在错误线程上访问的托管对象。

更糟糕的是,如果您尝试使用这些对象,您还会遇到错误访问错误。 ManagedObjects 不像普通的 NSObjects。 managedObject 只是一个 objectId 和一个指向上下文的指针。每当它需要访问其属性时,它会将请求转发到上下文。因此,如果该上下文被删除,那么这些对象将无法工作。在您的代码中,当函数结束时,支持结果的上下文将从内存中删除。 (注意:上下文并不总是立即删除。 在调试环境中,上下文可能会保留一段时间。在生产中,它会在函数结束时立即释放)。

因此访问该函数的结果是非法的,原因有两个 - 1) 您在错误的线程上,以及 2) 它没有后备上下文。

有几个解决方案。一种是从 managedObject 复制您需要的值并返回数组或字符串,或自定义对象(NSObject 子类)。

另一种解决方案是在应用程序生命周期内的主上下文中进行提取。

或者,您可以将要使用的上下文传递给函数。调用者有责任确保只要需要托管对象,上下文就会一直存在。

关于ios - 核心数据私有(private)上下文 performAndWait 导致调试崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45793211/

相关文章:

ios - swift 非空函数应该在 guard let 中返回一个值

ios - 错误域 = PlugInKit 代码 = 13 "query cancelled"UserInfo = {NSLocalizedDescription = 查询已取消} 与 Objective C Xcode 9.3 iOS 11

ios - 导致错误的 Swift 3 更新

iOS 核心数据 NSCocoaErrorDomain 134020

ios - NSBinaryStoreType 有什么优点?

ios - append 字典,iOS,Swift

ios - 随机删除自定义 UIView Not Working swift 3

ios - 单个 UIViewcontroller 中的两个 UITableView 无法正常工作

iOS 通用链接打开应用程序,不触发应用程序委托(delegate)方法

ios - Xcode 8 无法打开 Model.xcdatamodeld