-objectRegisteredForID:和--existingObjectWithID之间有什么区别:错误:?

问题描述 投票:16回答:4

获取托管对象之间的区别是什么

- (NSManagedObject *)objectRegisteredForID:(NSManagedObjectID *)objectID

- (NSManagedObject *)existingObjectWithID:(NSManagedObjectID *)objectID error:(NSError **)error

什么是“注册”对象? “已注册”对象和“未注册”对象之间有什么区别?

iphone core-data
4个回答
17
投票

什么是“注册”对象?

从我使用这些方法的结果来看,已注册的对象是已被提取到MOC中的对象。如果对象存在于持久性存储中但尚未获取,则将其objectID提供给objectRegisteredForID方法将返回nil。

如果没有提取它,你甚至可以拥有它的objectID?好吧,我在实现Revert例程时访问了这个问题。我通过用旧版本替换数据库来转储任何未保存的更改,清除上下文然后重新访问它。但我希望能够将用户选择的对象恢复到表的缓存中。因此,在进行返回之前,我隐藏了用户在数组中选择的objectID。然后,在返回之后,我使用stashed objectID重建了表缓存。

当我使用这些隐藏的objectID调用objectRegisteredForID时,它总是返回nil。 (但是如果我在获得一个新的上下文之前对它进行了测试,那么它将返回相应的对象 - 在那时它是一个被提取的,被加载的对象。因此我推断出“已注册”的含义。)

当我使用这些stashed objectID调用objectWithID时,一切都很好,除非在最后一次保存后删除了对象,在这种情况下它将不再存在于数据库中,并且无效但非nil返回将导致异常。

所以我使用了existingObjectWithID:error。如果对象仍然存在,则返回。如果它不再存在,则返回为零,错误的localizedDescription将为“尝试访问未在商店中找到的对象”。


6
投票

事后数年:

正如Wienke所怀疑的那样,已注册的对象是那些已经在内存中的对象。所以objectRegisteredForID:只有在其他人之前已经获得该对象时才会返回一个对象。

objectWithID:将返回一个对象,如果它当前存在于持久性存储中。

所以真正重要的区别是:

objectWithID可能去持久性商店。

注意推论:objectWithID可能必须执行获取。这意味着锁定商店。所以:

  • 如果商店已被其他人锁定,objectWithID可能会阻止,而objectRegisteredForID将永远不会阻止;和
  • 假设你有一个包含30个对象ID的数组并且你为每个对象执行了objectWithID,你可能会有30次单独去商店 - 检查这些对象是否已经注册然后,如果有的话,它会快得多,使用NSFetchRequest来完成剩下的工作。请注意,self in X查询可以接受一个或一组对象ID来返回实际对象,即使这在技术上并不完全符合'self'的正常Objective-C含义。

如果您有任何需要预取的关系路径,那么回退NSFetchRequest通常也是首选。因此,可能会获得相当多的性能。


1
投票

对于你的第一个问题:

objectRegisteredForID:是获取对象的快捷方式 - 它可以返回你的对象,也可以返回nil,让你知道它不能。当你已经知道为什么结果可能是零或者你不关心时,你就使用它。

existingObjectWithID:error:是类似的,因为它返回你的对象或nil,但另外,如果你传递一个错误参数,它会告诉你为什么它返回nil。如果您计划执行任何类型的错误报告(日志消息或警报)或错误处理(或许您计划采取不同的操作,可能需要执行此操作,具体取决于返回的错误类型)。

编辑:另外(每个文档),如果没有已在上下文中注册的给定ID的托管对象,则相应的对象会出现在上下文中。

我建议你打破“什么是注册对象?”你的问题的一部分是一个单独的问题,以便于获得更好的答案(基于匹配问题的主题行),并帮助可能来寻找答案的未来的探险者。


1
投票

我最近很困惑为什么registeredObject(for objectID: NSManagedObjectID)返回nil,但有一个简单的解释:我取出的NSManagedObject实例没有被保留:我从他们那里提取了我需要的信息并让它们被解除分配,这似乎是“取消注册”它们托管对象上下文,尽管可以使用NSManagedObjectContext上的其他方法轻松检索它们。我发现CoreData文档真的很糟糕:“注册”只是众多区别中没有明确解释的区别之一。

© www.soinside.com 2019 - 2024. All rights reserved.