NSManagedObjectContext objectWithID 生命周期方法(派生属性)

Posted

技术标签:

【中文标题】NSManagedObjectContext objectWithID 生命周期方法(派生属性)【英文标题】:NSManagedObjectContext objectWithID lifecycle method (derived property) 【发布时间】:2014-02-10 21:08:09 【问题描述】:

我有一个带有瞬态属性的NSManagedObject 子类,它基本上是对持久性对多关系之一的重新格式化。我通过观察与KVO的关系并在-awakeFromFetch-awakeFromInsert等中注册观察者来做到这一点。

这一切都很好,但是如果我使用对象的objectID-objectWithID: 技术在线程之间传递对象,则没有生命周期方法可以挂钩瞬态属性的生成。事实上,没有任何生命周期方法被触发,因为直接使用 id 访问对象似乎不被视为获取。

有一些方法可以解决这个问题,但最好使用基于生命周期的技术。我可能错过了什么吗?我可以使用另一种标准方法吗?

谢谢

编辑:示范项目 https://mega.co.nz/#!UsNBTZ7S!UU1qaFuc4W6Z2EYey-9AiMyfM8203Zfrm1lfpG5QITU

【问题讨论】:

【参考方案1】:

当您在具有上下文的一个线程上拥有一个 NSManagedObject 实例,然后从另一个线程和不同上下文中检索它时,-awakeFromFetch-awakeFromInsert 会触发。

您是否正确使用上下文以便检索新实例?

您是否查看过调试器中的指针以确保您正在与NSManagedObject 的新实例通信?

根据我的经验,这些生命周期方法会根据上下文触发。

【讨论】:

检查我的演示项目:这说明了问题所在。请注意,我不是在主线程上执行获取请求,而是使用对象的标识符直接使用objectWithID: 加载对象。请注意,awakeFromInsert 在初始插入时被调用,但awakeFromFetch 在使用objectWithID: 将对象插入主上下文时 调用。是的,它们是预期的独立对象实例。以这种方式将对象插入上下文时,似乎无法对对象执行其他操作...? 我无法下载您的演示应用程序,它一直超时。可以转发吗?【参考方案2】:

好的,所以回答我自己的问题,这个问题是因为objectWithID: 总是返回一个对象,即使该对象没有在接收者托管对象上下文中注册。在某些情况下,objectRegisteredForID: 似乎信息量更大。无论如何,结论是生命周期方法确实会触发,但要小心objectWithID:,因为它可能导致对象不一致。

【讨论】:

【参考方案3】:

我遇到了同样的问题,并通过在 NSManagedObjectContext 上创建一个通过正常获取路径的扩展来解决它,从而触发所有预期的生命周期方法:

extension NSManagedObjectContext 
    func fetchObject<T: NSManagedObject>(with objectID: NSManagedObjectID) -> T? 
        let request = T.fetchRequest()

        request.predicate = NSPredicate(format: "SELF = %@", objectID)
        guard let result = try? fetch(request) else 
            return nil
        

        return result.first as? T
    

【讨论】:

以上是关于NSManagedObjectContext objectWithID 生命周期方法(派生属性)的主要内容,如果未能解决你的问题,请参考以下文章

NSManagedObjectContext:撤消保存操作?

声明 NSManagedObjectContext 时出错

CoreData 多 NSManagedObjectContext 保存通知说明

NSManagedObjectContext 类别

NSManagedObjectContext: performBlockAndWait vs performBlock 通知中心

如何清除 NSManagedObjectContext 中的所有对象?