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:撤消保存操作?
CoreData 多 NSManagedObjectContext 保存通知说明
NSManagedObjectContext: performBlockAndWait vs performBlock 通知中心