NSPersistentContainer的loadPersistentStores的completionHandler是不是同步运行?

Posted

技术标签:

【中文标题】NSPersistentContainer的loadPersistentStores的completionHandler是不是同步运行?【英文标题】:Does the completionHandler of loadPersistentStores of NSPersistentContainer run synchronously?NSPersistentContainer的loadPersistentStores的completionHandler是否同步运行? 【发布时间】:2017-07-30 09:13:13 【问题描述】:

在苹果的NSPersistentContainer文档中,该方法有如下描述:

func loadPersistentStores(completionHandler block: @escaping (NSPersistentStoreDescription, Error?) -> Void) 块:一旦持久存储的加载完成,该块将在调用线程上执行。

但经过多次调试堆栈跟踪,我很确定 completionHandler 是同步执行的。如果我在调用 loadPersistentStores 之后添加打印语句,它总是在 completionHandler 执行后打印。

那么,我是否应该考虑当 loadPersistentStores 返回时,NSPersistentContainer 已经加载(无论成功与否)?

【问题讨论】:

【参考方案1】:

在我能找到的任何地方都没有清楚地解释这一点,但检查文档会得出一些可能的答案。

首先,NSPersistentStoreDescription 有一个名为shouldAddStoreAsynchronously 的标志,默认为false。如果您不修改容器的描述来设置标志,那么它们会同步加载。这与您所看到的相符。

我不认为这是专门针对持久容器选项的。然而WWDC 2016 "What's New in Core Data" 会话在NSPersistentStoreCoordinator 的上下文中解释了同样的事情,使用新的(从ios 10 开始)方法addPersistentStore(with:completionHandler:)。如果您使用异步加载标志,则加载异步进行,否则您将获得默认的同步加载,这是迄今为止唯一的选择。

基于此,我认为您所看到的是正确的:加载将是同步的,除非您指出它应该是异步的。如果您将shouldAddStoreAsynchronously 设置为true,那么我会期待不同的行为。对于同步加载,完成块仍然有用,因为这是报告错误的地方。

还值得记住的是,如果您添加多个 NSPersistentStoreDescriptionloadPersistentStores 可能会加载多个商店。在这种情况下,可能会多次调用完成块。

【讨论】:

以上是关于NSPersistentContainer的loadPersistentStores的completionHandler是不是同步运行?的主要内容,如果未能解决你的问题,请参考以下文章

如何处理 NSPersistentContainer.loadPersistentStores 中的错误?

NSPersistentContainer的loadPersistentStores的completionHandler是不是同步运行?

NSPersistentContainer, performBackgroundTask, 调用 perform 啥都不做

NSPersistentContainer,performBackgroundTask,调用perform什么都不做

NSPersistentContainer newBackgroundContext 的最佳实践是啥?

使用 NSPersistentContainer 实现核心数据并发