如何在单个托管对象上下文中初始化新的 NSManagedObject 并设置与另一个 NSManagedObject 的关系?

Posted

技术标签:

【中文标题】如何在单个托管对象上下文中初始化新的 NSManagedObject 并设置与另一个 NSManagedObject 的关系?【英文标题】:How do I initialize a new NSManagedObject and set a relationship to another NSManagedObject within a single managed object context? 【发布时间】:2017-02-10 15:48:35 【问题描述】:

我正在创建一个新的 NSManagedObject 并尝试与另一个 NSManagedObject 建立关系,但我收到此错误:

非法尝试在对象之间建立关系“提升” 不同的语境

我知道为什么会这样 - 我只是不知道如何解决它。

我正在调用这个函数来创建新对象:

func createNewLiftEvent() -> LiftEvent 
    let entity = NSEntityDescription.entityForName("LiftEvent", inManagedObjectContext: moc!)
    let newLiftEvent = LiftEvent(entity: entity!, insertIntoManagedObjectContext: moc)

    return newLiftEvent

我的 LiftEvent 实例在初始化时设置了自己的值。在 awakeFromInsert 中,调用了三个辅助方法,它们使用了一个名为 LiftEventDataManager (dataManager) 的类,这当然是创建第二个我不想要的 managedObjectContext 的原因:

override func awakeFromInsert() 
    super.awakeFromInsert()

    let defaultUnit = getDefaultWeightUnit()  // returns an NSManagedObject
    self.weightUnit = defaultUnit

    let defaultLift = getDefaultLift() // returns an NSManagedObject
    self.lift = defaultLift

    let defaultFormula = getDefaultFormula() // returns an NSManagedObject
    self.formula = defaultFormula

    self.maxAmount = 0.0

这是其中一种辅助方法的示例:

func getDefaultFormula() -> Formula 
    let formulasArray = dataManager.fetchSelectableFormulas() // this is what creates a new managedObjectContext
    let defaultFormula = NSUserDefaults.formula().rawValue
    formula = formulasArray[defaultFormula]
    return formula

createNewLiftEvent() 函数与上面的辅助函数中调用的 .fetchSelectableFormulas() 方法等方法一起位于 LiftEventDataManager 类中。

Apple 的核心数据编程指南没有说明这个特定问题,我也没有在 SO 上找到任何线程来解决初始化时的多上下文问题。

如何在“上下文 A”中创建新的 LiftEventObject 并获取其他托管对象并将它们放入“上下文 A”中以便我可以设置关系?

【问题讨论】:

【参考方案1】:

一种选择可能是传递您的原始 LiftEvent 对象,并让您的辅助方法使用 LifeEvent 的 managedObjectContext 来做他们的事情(所有托管对象都有对其上下文的引用,因此您可以利用这一事实)。

(可能不适用,但仅供参考,如果线程发挥作用,请小心。您可能还需要使用 performBlockAndWait)

【讨论】:

谢谢,康纳奇。如果我理解您的建议,那将意味着创建 LiftEvent 并将与其他托管对象的关系基本上为零,然后在其他地方设置它们。我认为问题在于我想在初始化 LiftEvent 对象时建立这种关系,因为我希望该对象能够完全初始化自己,以便在将其提供给我的视图模型时可以使用。 我正在考虑修改您的辅助方法以获取上下文,并在您的 awakeFromInsert 中传入 self.managedObjectContext。这样,辅助方法将使用与 LiftEvent 对象相同的上下文。 啊,我明白了。我想如果 LiftEvent 在调用 awakeFromInsert 时处于其上下文中(我认为是),那可能会起作用。我试试看。

以上是关于如何在单个托管对象上下文中初始化新的 NSManagedObject 并设置与另一个 NSManagedObject 的关系?的主要内容,如果未能解决你的问题,请参考以下文章

iOS CoreData+MoGenerator:如何仅在使用嵌套上下文时初始化托管对象一次?

如何在托管对象上下文之外使用核心数据对象?

如何在核心数据中保存单个实体

如何删除子托管对象上下文中的临时对象?

如何通过应用程序委托使用托管对象上下文实例化还原的视图控制器?

当对象的上下文不同时,如何制作 NSManagedObject 的浅拷贝?