错误 - 在批量插入期间设置关系时不同上下文中的对象

Error - objects in different contexts when setting relationship during a batch insert

我有一个函数用于在我的应用程序中创建对象图以进行测试。目前数据结构非常简单,Patient和ParameterMeasurement实体之间是一对多的关系。

由于测试状态的设置涉及大约 800 个条目,因此将其作为批量插入进行是有意义的......直到您尝试建立 ParameterMeasurement 和 Patient 之间的关系(反过来,它是一个一对一)此时应用程序崩溃并出现可怕的“非法尝试在不同上下文中的对象之间建立关系'cdPatient'

我很难理解为什么会发生这种情况,因为 Patient 和 ParameterMeasurement 实体都是使用调用者传递给函数的相同托管对象上下文创建的。

我已经尝试存储 Patient 的 objectID(在实例化 ParameterMeasurement 实例之前创建),然后在批量插入闭包中创建 Patient 实例的本地副本(代码在下面,但注释掉了)但是这个不能解决问题。我也检查了我的模型(一切正常,关系很好),删除了应用程序并重置了 sim 但仍然没有快乐。

最后,我坚持使用 print 语句来检查在实例化时与两个实体关联的 MOC 以及传递给函数的 MOC。正如预期的那样,内存地址匹配,这使得错误消息看起来像是一条红鲱鱼。

谁能指出我正确的方向?这似乎是过去的一个常见问题(5 年前有很多关于 ObjC 的帖子,但在 Swift 中很少),但是上面的例子没有处理这个特定的场景。

func addSampleData(to context: NSManagedObjectContext) throws {
    try addParameterDefinitions(to: context, resetToDefaults: true)

    let fetchRequest = ParameterProfile.fetchAll
    let profiles = try context.fetch(fetchRequest)

    for _ in 1...10 {
        let patient = Patient(context: context)
        patient.cdName = "Patient \(UUID().uuidString.split(separator: "-")[0])"
        patient.cdCreationDate = Date()

        //            let patientID = patient.objectID

        for profile in profiles {
            let data: [(Date, Double)] = DataGenerator.placeholderDataForParameter(with: profile)

            var idx = 0
            let total = data.count

            let batchInsert = NSBatchInsertRequest(entity: ParameterMeasurement.entity()) { (managedObject: NSManagedObject) -> Bool in
                guard idx < total else { return true }

                //                    let patientInContext = context.object(with: patientID) as! Patient
                if let measurement = managedObject as? ParameterMeasurement {
                    //                        measurement.cdPatient = patientInContext
                    measurement.cdPatient = patient
                    measurement.cdName = profile.cdName
                    measurement.cdTimestamp = data[idx].0
                    measurement.cdValue = data[idx].1
                }

                idx += 1
                return false
            }

            do {
                try context.execute(batchInsert)
                try context.save()
            } catch {
                fatalError("Import failed with error: \(error.localizedDescription)")
            }
        }
    }
}

核心数据模型定义:

对此进行了更多挖掘,似乎无法使用批量插入将关系添加到持久存储 as noted here。我猜这是因为在此过程中与正确关联实体相关的困难 - 令人沮丧但不会破坏交易。

现在,我将恢复到实体的单独插入,尽管我可以分两次完成该过程,即批量插入“基本”属性和第二次设置插入实体的关系。不过,在这个级别上似乎付出了太多的努力,而且对于额外的代码复杂性(以及错误的风险!),任何时间节省都可能是最小的!