UIManagedDocument vs NSManagedObject:性能

Posted

技术标签:

【中文标题】UIManagedDocument vs NSManagedObject:性能【英文标题】:UIManagedDocument vs NSManagedObject: Performance 【发布时间】:2014-02-26 01:33:24 【问题描述】:

我正在尝试编写一个 ios 笔记应用程序,该应用程序可以非常快速地处理大量笔记,并且可以在不阻塞 UI 的情况下进行同步。 (别担心,这只是一个学习项目,我知道 iOS 有十亿个笔记应用程序)。我决定使用 Core Data(主要是因为 Brent Simmons 关于 Vesper 的出色帖子)。我知道 UIManagedDocument 可以进行异步读取和写入,并且内置了很多功能,所以我想知道是否有任何信息表明对于一个相当简单的笔记应用程序来说会更快。除了集中的、基本上单例的、持久的存储之外,我真的找不到很多关于人们使用 UIManagedDocuments 的信息。它适用于 1000 份文件吗?它会比 NSManagedObjects 的数据库更快还是更慢?似乎我能找到的关于 Core Data 的大多数信息都是面向使用 NSManagedObject 的人,所以任何关于在生产应用程序中使用的 UIManagedDocuments 的信息都会非常有帮助。在这一点上,我唯一能想到的就是双向编写整个应用程序,加载 10,000 条笔记,看看会发生什么。

更新 澄清一下,我不是在学习 iOS 开发和 Objective-C,“学习项目”主要意味着我从未使用过 Core Data,并且想学习如何编写一个真正高性能的 Core Data 应用程序。

【问题讨论】:

Core Data 是 iOS 核心框架的一部分。它与其他操作系统/库一样是封闭源代码,并且几乎没有记录。它比写入 plist 文件更有文档记录:) 【参考方案1】:

UIManagedDocument 设计/旨在用于基于文档的应用程序。每个文档一个 UIManagedDocument 实例。如果您不构建基于文档的应用程序,那么您应该使用UIManagedDocument

人们喜欢UIManagedDocument 的所有事情都可以直接使用Core Data 堆栈轻松完成。 UIManagedDocument 将您从持久层所做的事情中抽象出来。你真的不想要的东西。

如果您想要一个高性能的 Core Data 应用程序,您不想使用UIManagedDocument。你会遇到它的问题。它会随机执行某些操作并导致性能问题。

正确地学习框架,你会好很多。

就 Vesper 而言,这些不是文件;它们太小了。将文档视为 Word 文件或 Excel 文件。 100% 相互隔离的大型复杂数据结构。

此外,无论您是否使用UIManagedDocument,您都将使用NSManagedObject 实例。 NSManagedObjectNSManagedObjectContextNSPersistentStoreCoordinator 都是 Core Data 中的基础对象。 UIManagedDocument 只是上面的一个抽象层。

最后,Core Data 不是数据库。这样想会让你陷入困境。 Core Data 是一种可以持久化到磁盘的对象模型,其中一种持久化格式恰好是 SQLite。

更新(遇到问题)

UIManagedDocument 是核心数据之上的抽象。要使用 UIManagedDocument,您实际上需要了解更多关于 Core Data 的知识,而不是仅使用主要的 Core Data 堆栈。

UIManagedDocument 在内部使用父/子上下文。还不明白吗?见上点。这也意味着您对它的保存请求是“在建议下采取的”,而不是当场被保存。如果您不了解它的意义或不想在需要时保存它,这可能会导致意想不到的结果。

UIManagedDocument 使用异步保存,您最多可以请求它保存。并不意味着它现在要保存,也不意味着您可以轻松停止并等待保存完成。你需要相信它会完成它。此外,它可能会在不合时宜的时候决定保存。

当您开始寻找 Core Data 的性能提升时,您往往希望以非常具体的方式构建堆栈,以最大限度地提高应用程序的收益。这取决于应用程序,并且使用 UIManagedDocument 中的摘要,您很快就会受到限制。

即使在构建基于文档的应用程序的情况下,我仍然不会使用UIManagedDocument。就在幕后。

【讨论】:

不是每个人都愿意/有能力在第一天投入时间正确学习框架,有些应用程序不需要纯 Core Data 的灵活性。你和我可能已经花时间学习 Core Data,并且可能总是用它编写我们自己的自定义调用,但是当 Apple 委托这些便利课程时,他们考虑到了一些开发人员和应用程序的受众。一些较新的开发人员可能更容易通过运行基本应用程序而上瘾,然后对 Core Data 的可能性产生足够的兴趣以深入挖掘,甚至可能购买一本关于该主题的书?... 最好使用 Apple 提供的模板来为这些开发人员提供服务,这些模板使用UIManagedDocumentUIManagedDocument 以非常不友好的方式做事,需要经验才能理解。当你第一次接触 Core Data 时,仅仅异步打开是非常难以理解的。然后考虑到在其UIManagedObjectContext 上调用-save 并不会真正将其保存到磁盘以及许多其他有趣的事实使其不适合作为学习工具。 我同意你,一般来说 UIManagedDocument 不会是我去核心数据的“你好世界”。 OP 听起来像是一个已经了解单例和同步性的入门者,我读到(或者可能误读)他的问题是“我应该抽象地学习核心数据并尝试将其应用于 Docs,还是通过模仿 Apple 调用我的具体项目?”在这两个极端之间,我的建议是使用 UIManagedDocument 作为跳板。我认为我们都可以鼓励 OP 投资于 Core、GCD 和 NSOperationQueue 的学习曲线。他们是值得的。 @ryancumley 如果核心数据太复杂而无法学习,那么您不应该使用任何基于核心数据的解决方案。因为那时您需要了解该解决方案的工作原理并且仍然了解核心数据的工作原理。就我个人而言,我只是将笔记存储在磁盘上的纯文本文件中,并带有一个用于元数据的 SQLite 文件(或者哎呀,甚至只是一个二进制 plist ......只要性能非常快,它们就可以处理一百万条左右的记录内容将适合 RAM 属性列表非常快)。 感谢@AbhiBeckert!我不是在谈论只学习一个或另一个,我在谈论首先要学习什么。从我们对 OP 的简短了解来看,在我看来,他是那种可以使用 UIManagedDocument 作为 Core 和 GCD 等的良好启动点的人,而不是永远代替它。这是“这是一本关于 GCD 的书”与 Apple 如何专门将 GCD 应用到您当前感兴趣的问题之间的区别。这两种学习方式都不正确,我只是向 OP 提出了我如何处理它的意见鉴于我对他的了解。【参考方案2】:

性能可能归结为其余代码的实现方式,而不一定是 UIManagedDocument 或 NSManagedObject 之间的区别。

将 UIManagedDocument 视为 CoreData 的特定小众实现,它已经将您想要的 CoreData 部分融入其结构中,从而为您(开发人员)节省一点编写代码的时间。它专为处理 UIDocument 和多线程而构建。 在幕后,UIManagedDocument 很可能与您一样使用 CoreData(假设您知道自己在做什么),但理论上您可以通过了解您的实施的确切和空洞细节来走捷径。

如果您不熟悉 CoreData、GCD 和 NSOperationQueue,那么您可能会通过利用 UIManagedDocument 而不是自己动手来节省大量的开发时间。

一个非常恰当的类比是使用 NSFetchedResultsController 来运行您的 UITableView,而不是滚动您自己的 CoreData 和 UITableView 实现。

如果您是 Objective-C 的新手,我建议您首先使用 UIManagedDocument 尝试一些功能。稍后您会迷失在 dispatch_asynch() 和 NSFetchRequest 的杂草中,并在这里和那里获得几毫秒的性能。

干杯!

【讨论】:

UIManagedDocument 不打算用作应用程序的唯一堆栈。它旨在用于基于文档的应用程序。使用它可以在项目开始时为您节省 10 分钟的时间,并在结束时花费您数小时/数天/数周的时间来调整性能并再次将其恢复。 公平点,虽然我不确定我的回答暗示你可以将 UIManagedDocument 用作完整堆栈(你能引用我给出这种印象的地方吗?)。我将它等同于 NSFetchedResultsController,它也不是一个完整的数据堆栈,而是一个预先打包的工具,用于删除围绕 CoreData 的一个特定用途的一些胶水代码。我是否可以谦虚地建议一些开发人员会花费 10 多分钟来成功设置 Core 和 GCD,并且会很乐意使用 Apple 风格的预设? 绝大多数开发人员使用 Apple 的模板,因此与自己编写堆栈的开发人员相比,他们花费的时间更少。我对唯一堆栈的评论适用于阅读您答案的每个人。开发人员不会使用UIManagedDocument 来节省时间。 谢谢,我添加了关于我真正想要学习的内容的更新,但如果我是 Objective-C 和 Cocoa 的新手,我可能对 UIManagedDocument 更感兴趣。【参考方案3】:

只需在磁盘上为每个音符存储一个纯文本文件。

保留一个单独的数据库(使用 sqlite 或者可能只是 -[NSDictionary writeToFile:atomically])来存储元数据,例如每个注释的最后一次用户修改日期和最后一次服务器同步日期。

定期与服务器通信,向其询问自上次同步以来发生变化的内容列表,并在您端发送在同一时间段内发生变化的所有数据。

只要您的笔记文件少于一百万,这应该非常快。在 NSOperationQueue 上执行所有网络和文件系统操作。

【讨论】:

以上是关于UIManagedDocument vs NSManagedObject:性能的主要内容,如果未能解决你的问题,请参考以下文章

UIManagedDocument 的迁移问题

UIManagedDocument 和 NSFetchedResultsController

从 UIManagedDocument 到普通堆栈的核心数据迁移

UIManagedDocument - 验证核心数据实体

保存 UIManagedDocument 时应用程序崩溃

自动保存不适用于 UIManagedDocument 上的 NSUndoManager