2013-11-04 48 views
1

过去几天我已经做了大量的研究,但我不确定当前的最佳做法是什么对于并发核心数据。最相关的帖子似乎是这个​​,但根据this analysis关于不同并发方法的表现,似乎现代方式与父上下文可能不是最好的。此外,来自Apple的this example未实施建议不使用默认NSConfinementConcurrencyType的Apple's own concurrency guide中提到的最佳做法。简单的并发核心数据

鉴于所有这些,使用Core Data实现并发的最简单和最好的方法是什么?我只需要一个后台线程,在不挂断用户界面的情况下对Core Data进行一些长时间的写操作。代码示例表示赞赏。

回答

0

一如既往,它真的取决于你想要完成什么。

无论您实施的架构如何,“长时间写入”都会挂起您的用户界面。
写入操作会锁定操作系统级别和sqlite引擎级别的数据库文件(如果您使用这种类型的存储),所有挂起的读取操作必须等待写入完成才能结束。
最常用的优化方法之一是将数据库“加载”过程与多个保存操作分开(您不应该介意在后台发生这种情况)。

因此,要回答这个问题:
你最简单的方法,很可能会使用在你提到的(父子层次)的博客文章中描述的架构。如果你注意到这个原因对你的用户界面来说太“口吃”,试着优化你的数据加载过程或者尝试一个不同的架构。
使用仪器在您的应用程序执行中找到“瓶颈”。

CodeData在我知道的每个架构中都有“怪癖”/错误,您会逐渐发现它们,这取决于您的使用情况。

+0

在什么情况下读取必须等待写入完成?我认为有两个上下文,一个用于阅读,另一个用于写作可以解决这个问题(除了可能在合并更改时)。另外,你可以详细了解一下你发现了什么样的“怪癖”吗? – GLee

+0

写入操作会锁定持久存储协调器(在CoreData中,我注意到即使是读取操作也会锁定PSC)。这意味着任何其他操作(从任何情况下)都不可能通过该PSC进入商店。另外,写入操作会将文件锁定在SQLite引擎级别(以防止部分写入,然后在写入结束之前读取损坏的数据)。最后,写入操作从相同的原因锁定OS级别的文件。 –

+0

至于“怪癖”/ bug ...主要是在上下文之间的变化以及取得的结果控制器对它们的反应之间进行合并。或父 - 子架构中的不可捕获异常(与在多对多关系中访问已删除对象有关)。还有更多内容,但是它本身就是一篇文章...... –

0

我的建议是与父/子上下文模式。根据您提供的稀疏细节(例如记录数量,数据总量,交付延迟等)。这似乎是最灵活和经过验证的解决方案,也可以容纳非常大的数据集。

与其他声明相反,无论“写入”对您的数据库有多长时间,您都可以拥有流畅的操作UI。显然,这是后台线程的用途。保持UI流畅的机制是通过所谓的数据更改通知。您可以在不影响用户体验的情况下对这些做出反应。

您对NSConfinementConcurrencyType的评论是正确的。正如你的来源所述,它是为了向后兼容,所以你可以忘记它。显然,为了实现并发性,您在创建上下文时要使用NSPrivateQueueConcurrencyType

+0

长时间保存(需要几秒钟时间)锁定PSC,PSC锁定期间触发的任何读取/故障将等待保存完成= =>如果UI尝试获取未缓存的数据,UI将会出现口吃。将数据加载分割成更小的块将减少PSC和UI结尾的锁定时间。使用WAL也可能有所帮助。 –