从 UIManagedDocument 到传统的 Core Data 堆栈
Posted
技术标签:
【中文标题】从 UIManagedDocument 到传统的 Core Data 堆栈【英文标题】:From UIManagedDocument to traditional Core Data stack 【发布时间】:2012-09-03 18:44:34 【问题描述】:我使用 UIManagedDocument 创建了一个新应用程序。虽然在我的设备上一切都很好,但我得到了很多差评,因为其他设备上存在问题:( 经过大量阅读和测试,我决定回到传统的 Core Data 堆栈。 但是,使用应用程序商店中已经存在的应用程序执行此操作的最佳方法是什么? 如何构建此更新?我应该注意什么?
谢谢, 斯蒂芬
【问题讨论】:
【参考方案1】:我认为您最好确定您的 UIManagedDocument 问题并解决它们。
但是,如果你想去普通的 MOC,你只需要担心几件事。最大的问题是 UIMD 将内容存储在一个文件包中,根据您的选择,您可能不得不担心更改日志。
最后,如果你想要一个单独的 sqlite 文件,并且你想减少混淆的可能性,你有一个类可以简单地打开你的 UIManagedDocument,并获取每个对象,然后将它复制到单个 sqlite 文件中以供你使用新的 MOC。
现在,您应该不需要不同的对象模型,因此您应该不会遇到任何迁移问题。
然后,只需删除保存 UIManagedDocument 的文件包,并仅使用您的单个文件 sqlite 存储。
基本上,在启动时,您会尝试打开 UIManagedDocument。如果它打开,加载每个对象并将其复制到新数据库中。然后删除它。
从那时起,你应该很高兴。
但是请注意,您现在可能会遇到一些 UI 延迟,因为所有数据库 IO 都发生在主 UI 线程上。要解决此问题,您可能需要使用单独的 MOC,并通过正常的 COreData 通知机制来协调更改。有大量的文档、示例和教程。
编辑
感谢您的回答。我对这些问题的问题是,我不是 能够复制它们。我所有的设备都工作正常。但我有一个 很多邮件,关于这样的问题: - 重复条目 - 没有数据 停止并重新启动应用程序后 - 有人说,该应用程序工作 好几天并停止工作(没有新数据)。这些都是 奇怪的事情,不会发生在我的设备上。所以对我来说最好的 方法是回到普通的MOC。我的数据库没有很多用户生成 数据,所有数据都是从webservice加载的,所以没问题 删除数据并开始使用新数据库。 – 乌克曼
重复条目。这听起来像是与临时/永久 ID 相关的错误。有很多关于那个的帖子。这是一个:Core Data could not fullfil fault for object after obtainPermanantIDs
不保存。听起来您没有为 UIManagedDocument 使用正确的 API。您需要确保不直接保存 MOC,并使用撤消管理器或调用 updateChangeCount:
通知 UIManagedDocument 它有您要保存的脏数据。同样,也有很多关于此的帖子。搜索updateChangeCount
。
但是,您最了解您的应用,使用纯 Core Data 可能会更好、更容易。
请记住,如果您要从网络进行大量导入,请使用单独的 MOC,并让您的主 MOC 监视 DidSave 通知,以便使用新导入的数据进行自我更新。
【讨论】:
感谢您的回答。我对这些问题的问题是,我无法重现它们。我所有的设备都工作正常。但是我收到了很多邮件,关于这样的问题: - 重复条目 - 停止并重新启动应用程序后没有数据 - 有人说,应用程序可以正常工作几天并停止工作(没有新数据)。这些都是奇怪的事情,不会发生在我的设备上。所以对我来说,最好的方法是回到普通的 MOC。我的数据库没有很多用户生成的数据,所有的数据都是从webservice加载的,所以删除数据并开始使用新的数据库是没有问题的。 你好!我得到了您的解决方案,直到我在新数据库中创建了所有对象。然而,关系缺失。您对这个问题有什么建议吗?【参考方案2】:UIManagedDocument 是一种特殊类型的文档,它是 UIDocument 的子类,它使用 Core Data Framework 存储其数据。因此,它结合了文档架构和核心数据功能的强大功能。
您可以从 Document Based App Programming Guide for ios 中阅读更多关于基于文档的体系结构的信息,我推荐 WWDC2011 使用 iOS5 会话视频在 iCloud 中存储文档。我还推荐斯坦福 CS193P:iPad 和 iPhone 应用程序开发(2011 年秋季)第 13 讲。
调用 saveToURL:forSaveOperation:completionHandler: 时创建的内容是 UIManagedDocument 和 UIDocument 的实现细节,您不必真正担心或依赖它。然而,在当前实现中,正在创建一个包含 sqlite 数据库文件的文件夹。
没有。所有实体都将包含在一个数据库文件中,通常也称为:持久存储。可以使用多个持久存储,但这些是更高级的用例,UIManagedDocument 目前使用一个。
UIManagedDocument 的上下文是指来自底层核心数据框架的 NSManagedObjectContext。 UIManagedDocument 实际上并行操作其中两个以将 IO 操作分拆到后台线程。当谈到上下文本身的性质时,这里引用核心数据编程指南:
您可以将托管对象上下文视为智能便签本。当您从持久存储中获取对象时,您将临时副本带到便笺簿上,它们在此处形成对象图(或对象图的集合)。然后,您可以随意修改这些对象。但是,除非您实际保存这些更改,否则持久存储将保持不变。
但是,看看我上面发布的讲座和其他材料,以大致了解所使用的技术以及它们在不同情况下对您作为开发人员的潜在价值,确实是一个好主意。
【讨论】:
以上是关于从 UIManagedDocument 到传统的 Core Data 堆栈的主要内容,如果未能解决你的问题,请参考以下文章
如何将现有的非文档核心数据存储转换为 uimanageddocument?