【问题标题】:Core Data Background Thread Returning Inserted NSManagedObject核心数据后台线程返回插入的 NSManagedObject
【发布时间】:2019-03-30 12:44:58
【问题描述】:

在我的应用程序中,我使用带有两个 NSManagedObjectContexts(viewContext 和背景上下文)的 NSPersistantContainer。我所有的读取操作都是在视图上下文中执行的,而我所有的写入操作都是在后台上下文中执行的(如下所示)。

创建一个新的 Animal 类

class func new(_ eid: String) {
    //Create Animal Entity
    let container = CoreDataService.persistentContainer
    container.performBackgroundTask { (context) in
        let mo = Animal(context: context)
        mo.eid = eid
        mo.lastModified = Date()
        mo.purchaseDate = Date()
        mo.uuid = UUID()

        do {
            try context.save()
        }
        catch let error {
            print(error)
        }
    }
}

我遇到的问题是我需要将新创建的 NSManagedObject (Animal) 返回到调用 Animal.new(eid) 的管理器类, 用于显示对象属性。

我尝试过使用完成处理程序,但在返回值时遇到了问题,就像在主线程中使用后台 NSManagedObject 一样。

使用可能的新功能

Animal.new(eid) { (animal) in
if let animal = animal {

}

返回在后台上下文中创建的新创建的 NSManagedObject 的最佳方法是什么?

【问题讨论】:

    标签: swift core-data background-thread


    【解决方案1】:

    我所做的是将我的 CoreData 托管对象保留在我的 CoreDataManager 类中,而不是将它们暴露给我的框架的其余部分。因此,要创建一个或多个托管对象的方法将接受数据作为非托管对象,然后创建托管对象但不返回它(因为调用者已经拥有非托管对象)。从 CoreDataManager 获取时,我会创建并填充一个非托管对象并返回它。

    现在我这样做的部分原因是因为我在框架中使用 CoreData,因此我永远不想将托管对象交给我的框架的客户端应用程序。但它也解决了您描述的其他问题。

    (当我编写应用程序时,我使用 Realm,这些对象可以直接进入应用程序的 UI 类,因为 Realm 更容易管理,呃,管理。:)

    【讨论】:

    • 您能否展示一些使用 unManagedObject 实现的代码?
    • 我所说的非托管对象,是指包含与CoreData托管对象相同属性的类,与CoreData无关。您只需编写代码将 CoreData 管理的对象的属性映射到此类的新对象。
    • 当我的 Animal 对象有多个关系时,您必须开始映射时才开始变得混乱。
    • 是的,但也有很多好处。您的代码库的其余部分不必小心遵循 CoreData 的规则。这些对象也更容易在调试器中看到。您只会在 CoreDataManager 中限制对 CoreData 对象的任何编辑,这也有助于调试。或许这里会有不一样的答案。
    • 另外:我在我的应用程序中使用 Realm 来避免此类问题......模式更容易定义和维护,我可以避免需要多个 moc 和线程混乱。很难正确编写并发 CoreData,主 moc 和后台 moc 在适当的时间同步。使用 CoreData,无论您多么小心,总会有一两次非常罕见的崩溃,您永远无法摆脱。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-09
    • 1970-01-01
    • 2012-11-14
    • 1970-01-01
    • 2012-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多