IOS核心数据异步保存
Posted
技术标签:
【中文标题】IOS核心数据异步保存【英文标题】:IOS Core Data asynchronous saving 【发布时间】:2016-07-22 08:35:34 【问题描述】:问题陈述
我无法异步保存服务器端数据。
结构
我正在使用以下结构的 NSManagedObjectContext 以从父到子的顺序:
-
writerManagedObjectContext (NSPrivateQueueConcurrencyType)
masterManagedObjectContext (NSMainQueueConcurrencyType)
backgroundManagedObjectContext (NSPrivateQueueConcurrencyType)
代码
我正在使用以下代码来保存数据
[backgroundManagedObjectContext performBlock:^
[backgroundManagedObjectContext save:nil];
[masterManagedObjectContext performBlock:^ // Starts blocking UI from here
[masterManagedObjectContext save:nil];
[writerManagedObjectContext performBlock:^
[writerManagedObjectContext save:nil];
]
]
]
问题
代码保存良好。 backgroundManagedObjectContext
也异步保存。但是,masterManagedObjectContext
和 writerManagedObjectContext
都拒绝异步保存并阻塞 UI 线程。 (我知道它阻塞了 UI 线程,因为我试图执行与 Core Data 无关的操作,它们也被阻塞了。这不是持久协调器无法访问的情况)
问题
-
上述代码阻塞主线程的原因是什么?
假设我可以从任何地方调用上述代码,因为
save
将在每个相应的线程/上下文中被调用,我是否正确?
任何帮助将不胜感激。
编辑
http://floriankugler.com/2013/04/29/concurrent-core-data-stack-performance-shootout/
显然冻结来自尝试传播到父 NSManagedObjectContext。这篇文章似乎回避了这样一个事实,即不可能将真正的异步保存到主要上下文中。
数据被高度链接,5MB,大约需要 40 秒才能保存到 psc。我不认为我会使用帖子中描述的并行结构,因为代码库已经很大了。如果我能利用任何策略来减少这种冻结,我将不胜感激。
【问题讨论】:
【参考方案1】:即使backgroundManagedObjectContext
是一个私有队列上下文,它仍然会将其更改传播到masterManagedObjectContext
,它是它的父级。这可能是它窒息的地方。合并子上下文中的更改仍会占用 CPU 时间,其影响在 UI 等繁忙队列中变得更加明显。
您始终可以使用 Instruments 来分析正在发生的事情。
如果您的特定用例允许,请尝试将backgroundManagedObjectContext.persistentStoreCoordinator
设置为与writerManagedObjectContext
相同的psc,而不是使其成为masterManagedObjectContext
的子代。
更好的是,使用像 MagicalRecord 这样的很棒的框架。不会使您免受此类问题的影响,但更少的代码使(可以说)更容易调试。
【讨论】:
我已经在使用嵌套 MOC,如结构所示。我的问题是尽管使用了嵌套的 MOC 结构,为什么保存不是异步的。 我意识到您在重新阅读您的帖子后使用了嵌套上下文。我会编辑我的答案。您应该避免将nil
传递给save
错误处理程序。您将希望能够对错误做出反应。尝试检查错误,看看这是否是你的主队列停滞的原因。您还提到了“服务器端”。你在使用 Core Data iCloud 同步吗?
我使用的是我自己的服务器,但老实说服务器是无关紧要的。基本上我正在解析 json 数据并将它们插入到 Core Data 中。我在做错误处理——上面的代码只是为了说明我的代码是什么样子的。
我尝试在同步期间定期暂停以查看是什么阻碍了我的主队列,我只能看到数据逐渐保存。我想我无法使用这种结构完全异步保存。考虑到在 android=( 中它是如此简单,这有点令人沮丧
是的......这就是我所怀疑的......我编辑的问题上的链接也没有得到你的回答。我可能最终会仔细选择何时保存我的主要 moc。和你讨论这个很有帮助!谢谢=)以上是关于IOS核心数据异步保存的主要内容,如果未能解决你的问题,请参考以下文章
iOS Swift 3核心数据-尝试递归调用-save的致命错误:上下文中止
异步获取大量资源并将它们“异步”保存到数据库中。使用哪种好模式? (AFNetworking,核心数据)