2010-08-12 40 views
6

我有关于核心数据的一些基本问题(我是新来的),我希望对当前的标准和实现有一些看法。关于典型用法的核心数据问题

基本上我有一个iPhone上的应用程序(支持iOS 3.0及以上版本),它通过HTTP从Web调用获取大量数据,我正在将结果移动到本地存储中,以便用户下次快速检索再次加载相同的数据(数据不会改变,这就是为什么我可以依赖缓存版本是准确的)。

我只是想先知道的几件事:

  1. 难道人们这些天治疗延伸NSManagedObject作为领域对象,还是你严格创建单独的类别进行存储和创建的helper方法管理对象创建它们到域对象?我有时会发现将所有持久性逻辑放在域外是一件好事。

  2. 如何清理?如何在应用程序关闭时删除所有数据,或者可能会在本地存储中删除数据?我当然不想在用户手机上随时保存数据。

  3. 核心数据是否有任何类型的原子性?我的实现将首先在本地检查Web服务之前检查数据,我想确保从未有一半数据集被提交到本地存储并获得有趣的结果。

  4. 我想运行一个公平的后台线程来获取背景中的数据,有什么事情我需要考虑什么时候在后台线程上持久化对象?

  5. 关于上述问题,创建“后台读取”循环的最佳方法是什么?在应用程序委托?每个视图,取决于视图?等等...?

我希望这些都不是太基本:)

感谢所有帮助你可以给。

回答

5

人做这些天治疗管理 对象扩展NSManagedObject作为 域对象,还是你创建 单独的类严格用于存储 和创建的helper方法来创建 他们到域对象?我有时 发现保持所有持久性逻辑出 该域名是一件好事。

如果您创建完全独立的域对象,你必须让他们同步你的核心数据模型,并保持核心数据和工作与这些对象之间的转换成本 - 加上你在内存中重复的对象,这取决于你有多少物体可能是一个问题。

但是,使用单独的域对象的好处是您不再被固定到托管对象上下文。一种情况是,如果您维护对托管对象的引用,然后某些后台操作导致主要托管对象上下文删除对象 - 现在如果您访问删除的托管对象中的任何属性,则会触发故障异常(即使你明确地加载了没有错误数据的对象)。

我曾尝试过适度成功的一件事是偶尔为特定用途使用非常轻量级的单独数据对象 - 我所做的是定义一个协议来表示数据对象访问器,并使用与核心数据访问器相同的名称。然后我有核心数据对象和一个自定义独立数据对象实现这个协议,并有一个机制来自动地将属性从一个复制到另一个。所以我没有将每个对象都做成自定义的,并且可以将来自本地商店的对象或独立对象替换为对象。

我没有明确的偏好,但仍偏向直接使用托管对象,因为缺少重复。您可以通过监听更改或使用核心数据控制器类来减轻不良的副作用。

有一件事情,有助于保持域对象和数据对象排序相同但不是,使用mogenerator生成数据对象。它会生成核心数据存储中对象的非常好的对象表示,以及要编辑的前端对象 - 向其添加自定义访问器或复杂方法。更改数据存储mogenerator重新生成数据对象,但只保留自定义代码。

http://rentzsch.github.com/mogenerator/

怎么样清理?一个 通常会在 应用程序关闭时删除所有数据,或者可能会在 中删除本地存储中的数据?我当然不想 在任何时候都想要在用户手机上保存数据。

数据通常足够小,我只是将它留在那里,并使用过期时间戳,以便您知道数据太旧而无法直接使用。由于用户频繁关闭和重新打开应用程序,因此保存数据的价值非常高,并且已经有数据,您可以在获取内容更新时立即呈现结果。

是否有任何类型的原子与 核心数据?我的实现将 首先检查本地数据在 击中网络服务之前,我想 确保从未有一半数据集被提交到本地 存储并得到有趣的结果。

原子性来自于您在上下文中执行操作,然后告诉上下文保存。所以真正的原子性意味着在你准备好之前避免其他组件发出一个保存,这通常意味着在自己的上下文中做一些事情并合并回主环境中。

我想运行一个公平的几个 后台线程在 取数据的背景,是否有在后台线程持续 对象时,我 需要考虑任何事情?

每个后台线程都需要自己的上下文,您应该听取保存通知并合并到当前的主上下文中。

您应该努力避免可能几乎同时保存到同一对象的重复请求,这有时会导致合并时出现核心数据错误。与此相关 - 在主要上下文中设置合并策略,因为默认策略是抛出异常。

这也意味着在建模过程中,尽可能多地使用单独的对象,而不是聚集来自许多不同来源的数据的一个大对象。

有关保存与合并到其他环境中的更多信息,请参见该问题:

CoreData and mergeChangesFromContextDidSaveNotification

关于上述问题, 什么是创建一个 “背景获取的最佳途径“循环?在应用程序 委托?每个视图取决于 视图?等等...?

我想从一个单独的单例类做到这一点(毕竟AppDelegate中本身就是一个单...),我可以在另外索要主要管理对象上下文具体到一个线程上下文。

这在启动新的Core Data项目时也很有用,您不必使用Core Data模板,只需重新使用此核心数据管理器即可。

+0

首先,感谢您花时间回答您的问题,+1为详细信息。我只有几个后续问题,1.您能否详细解释一下原子性?我只是没有真正关注你。 2.你提到了一个主背景,并且合并,我不熟悉这些,你是否也可以详细说明这些? 3.你如何管理每个线程的不同上下文?是否只是在创建线程时获取上下文的问题,然后一旦线程完成将该上下文“返回”到主线程并合并? – Mark 2010-08-12 06:29:52

+0

1)您在托管对象上执行所需的操作 - 在保存上下文之前,没有任何更改“粘住”。摆脱上下文(或恢复更改)就像是回滚。 对于2-3 - 这个想法是,你有一个主线程的上下文。在任何后台操作中,您都会基于同一个托管对象库创建一个新的上下文,然后在完成编辑时保存它 - 您可以查找特殊通知,在该方法中,您可以请求合并到主上下文中。看到http://stackoverflow.com/questions/1429900/coredata-and-mergechangesfromcontextdidsvenotification – 2010-08-12 07:19:03

+0

好吧,我明白你在说什么,再次感谢,如果你不介意我想继续问一些更多的问题,我知道这个网站真的没有成立讨论...为什么你需要在NSManagedObject的属性是@动态?如果您将它们用作域对象,那么使用@synthesize会更容易,但是当我更改时会出现错误... – Mark 2010-08-12 23:14:39