获取托管对象之间的区别是什么
- (NSManagedObject *)objectRegisteredForID:(NSManagedObjectID *)objectID
Run Code Online (Sandbox Code Playgroud)
和
- (NSManagedObject *)existingObjectWithID:(NSManagedObjectID *)objectID error:(NSError **)error
Run Code Online (Sandbox Code Playgroud)
什么是"注册"对象?"已注册"对象和"未注册"对象之间有什么区别?
Wie*_*nke 17
什么是"注册"对象?
从我使用这些方法的结果来看,已注册的对象是已被提取到MOC中的对象.如果对象存在于持久性存储中但尚未获取,objectRegisteredForID则将其objectID提供给该方法将返回nil.
如果没有提取它,你甚至可以拥有它的objectID?好吧,我在实现Revert例程时访问了这个问题.我通过用旧版本替换数据库来转储任何未保存的更改,清除上下文然后重新访问它.但我希望能够将用户选择的对象恢复到表的缓存中.因此,在进行返回之前,我隐藏了用户在数组中选择的objectID.然后,在返回之后,我使用stashed objectID重建了表缓存.
当我objectRegisteredForID使用这些隐藏的objectID 调用时,它总是返回nil.(但是如果我在获得一个新的上下文之前对它进行了测试,那么它将返回相应的对象 - 在那时它是一个被提取的,被加载的对象.因此我推断出"已注册"的含义.)
当我objectWithID使用这些存储的objectID 调用时,一切都很好,除非在最后一次保存后删除了对象,在这种情况下它将不再存在于数据库中,并且无效但非零返回将导致异常.
所以我用过existingObjectWithID:error.如果对象仍然存在,则返回.如果它不再存在,则返回为零,错误的localizedDescription将为"尝试访问未在商店中找到的对象".
事后数年:
正如Wienke所怀疑的那样,已注册的对象是那些已经在内存中的对象.因此,objectRegisteredForID:只有在其他人之前已经获得该对象时才返回对象.
objectWithID: 如果对象当前存在于持久性存储中,则返回该对象.
所以真正重要的区别是:
objectWithID 可能会去持久性商店.
注意推论:objectWithID可能必须执行获取.这意味着锁定商店.所以:
objectWithID可能会阻止,而objectRegisteredForID永远不会阻止; 和objectWithID为每个对象执行过,那么你可能会分别进行30次到商店的访问 - 检查这些对象是否已经注册然后,如果没有注册,则要快得多,用一个NSFetchRequest来得到剩下的.请注意,self in X查询可以接受一个或一组对象ID来返回实际对象,即使这在技术上并不完全符合'self'的正常Objective-C含义.如果您有任何需要预取的关系路径,那么回退NSFetchRequest通常也是首选.因此,可能会获得相当多的性能.
对于你的第一个问题:
objectRegisteredForID:是获取对象的快速简单的方法——它要么返回你的对象,要么返回 nil 让你知道它不能。当您已经知道为什么结果可能为零或者您不在乎时,您可以使用它。
existingObjectWithID:error:类似,因为它返回您的对象或 nil,但此外,如果您传递错误参数,它会告诉您为什么它返回 nil。如果您计划执行任何类型的错误报告(日志消息或警报)或错误处理(也许您计划根据返回的错误类型采取不同的操作,则可能需要执行此操作。
编辑:此外(根据文档),如果没有已在上下文中注册给定 ID 的托管对象,则相应的对象将被错误地放入上下文中。
我建议您分解“什么是注册对象?” 将问题的一部分拆分成一个单独的问题,以便于获得更好的答案(基于与问题匹配的主题行)并帮助未来可能寻求答案的探险者。
| 归档时间: |
|
| 查看次数: |
2440 次 |
| 最近记录: |