我有一些关于核心数据的基本问题(我是新手),我想对当前的标准和实现有一些观点.
基本上我在iPhone上有一个应用程序(支持iOS 3.0及更高版本),它通过HTTP从Web调用获取大量数据,我正在考虑将结果移动到本地存储中,以便在下次用户加载相同数据时快速检索再次(数据没有改变,这就是为什么我可以依赖缓存版本准确).
我只想先了解一些事情:
这些天人们如何处理NSManagedObject作为域对象扩展的托管对象,或者是否严格创建用于存储的单独类并创建辅助方法以将它们创建为域对象?我有时会发现将所有持久性逻辑保留在域外是一件好事.
清理怎么样?当应用程序关闭或者可能使本地存储中的数据过期时,通常如何删除所有数据?我当然不想在任何时候都在用户手机上保存数据.
核心数据是否存在任何类型的原子性?我的实现将在访问Web服务之前首先在本地检查数据,我想确保从未将半个数据集提交到本地存储并获得有趣的结果.
我想运行一些公平的后台线程来在后台获取数据,在后台线程上持久保存对象时是否需要考虑?
关于上述问题,创建"后台获取"循环的最佳方法是什么?在app代理?每个视图,视视图而定?等等...?
我希望这些不是太基础:)
谢谢你提供的所有帮助.
这些天人们如何处理将NSManagedObject扩展为域对象的托管对象,或者是否严格创建用于存储的单独类并创建辅助方法以将其创建为域对象?我有时会发现将所有持久性逻辑保留在域外是一件好事.
如果您创建完全独立的域对象,则需要花费它们与Core Data模型保持同步,并保持核心数据和这些对象之间的转换工作 - 而且内存中有重复的对象,具体取决于您拥有的对象数量这可能是一个问题.
但是,使用单独的域对象的好处是您不再与托管对象上下文结合.如果您维护对托管对象的引用,然后某些后台操作会导致主要托管对象上下文删除对象,那么这种情况可能会对您造成伤害,如果您访问已删除托管对象中的任何属性,则会触发故障异常(即使你明确地已经加载了没有故障数据的对象).
我尝试过一次成功的一件事是偶尔使用非常轻量级的独立数据对象用于特定用途 - 我所做的是定义一个表示数据对象访问器的协议,其名称与核心数据访问器相同.然后我有核心数据对象和自定义独立数据对象实现此协议,并有一个机制自动将属性从一个复制到另一个.所以我没有把每个对象都做为自定义,并且可以对待来自本地商店或独立交换的对象.
我对这个没有明确的偏好,但由于缺乏重复,因此倾向于直接使用托管对象.您可以通过侦听更改或使用核心数据控制器类来缓解不良副作用.
有助于保持域对象和数据对象不相同的一件事是使用mogenerator生成数据对象.它生成核心数据存储中对象的非常好的对象表示,以及您要编辑的前端对象 - 添加自定义访问器或复杂方法.在更改数据存储时,生成器会重新生成数据对象,但只保留自定义代码.
http://rentzsch.github.com/mogenerator/
清理怎么样?当应用程序关闭或者可能使本地存储中的数据过期时,通常如何删除所有数据?我当然不想在任何时候都在用户手机上保存数据.
数据通常足够小,我只需将其留在那里,并使用到期时间戳,以便您知道数据何时太旧而无法直接使用.由于用户如此频繁地关闭和重新打开应用程序,因此保留数据有很大的价值,并且数据已经存在,您可以在获取内容更新的同时立即显示结果.
核心数据是否存在任何类型的原子性?我的实现将在访问Web服务之前首先在本地检查数据,我想确保从未将半个数据集提交到本地存储并获得有趣的结果.
原子性来自于您在上下文中执行操作然后告诉上下文保存.因此,真正的原子性意味着在准备好之前避免其他组件发出保存,这通常意味着在自己的上下文中执行某些操作并合并回主上下文.
我想运行一些公平的后台线程来在后台获取数据,在后台线程上持久保存对象时是否需要考虑?
每个后台线程都需要自己的上下文,您应该监听保存通知并在那时合并到主上下文中.
您应该努力避免几乎同时保存到同一对象的重复请求,这有时会导致合并时出现核心数据错误.与此相关 - 在主上下文中设置合并策略,因为默认策略是抛出异常.
这也意味着在进行建模时,尽可能多地使用单独的对象,而不是聚合来自许多不同来源的数据的大型对象.
有关保存和合并到其他上下文的更多信息,请参阅此问题:
CoreData和mergeChangesFromContextDidSaveNotification
关于上述问题,创建"后台获取"循环的最佳方法是什么?在app代理?每个视图,视视图而定?等等...?
我喜欢从一个单独的单例类中执行此操作(毕竟,AppDelegate本身是一个单例...),除了特定于线程的上下文之外,我还可以请求主要的托管对象上下文.
这在启动新的Core Data项目时也很有用,您不必使用Core Data模板,只需重新使用此核心数据管理器即可.