如何使用Core Data有效保存UI /主线程中的更改?

时间:2010-04-09 16:27:22

标签: iphone cocoa-touch performance multithreading core-data

因此,这里有几篇关于将数据从外部数据源导入和保存到Core Data的帖子。 Apple为此记录了一个合理的模式:“导入并保存在后台线程中,将保存的对象合并到主线程”。一切都很好。

我有一个相关但不同的问题:用户正在修改UI和主线程中的数据,从而修改托管对象上下文(MOC)中某些对象的状态。我想不时保存这些变化。有什么好办法呢?

现在,您可以说我可以这样做:创建一个具有自己MOC的后台线程,并在那里传递更改后的objectID-s。对我来说,catch-22就是对象的ID在保存时会发生变化,我无法保证事情发生的顺序。根据对象之前是否已保存,我可能最终将不同的objectID传递给同一对象的后台线程,并且我不知道Core Data是否可以解析此问题并看到不同的objectID-s指向到同一个对象而不是为我创建重复项。 (我可以测试一下,但我先讨论这个问题。)

我有一个想法:我总是可以在后台线程上进行MOC保存,并使用operationqueue将它们排队,这样总有一个保存正在进行中。我不会创建一个新的MOC,我只会使用与主线程相同的MOC。现在,这不是线程安全的,当有人在主线程中修改MOC而在后台线程中保存时,结果可能是灾难性的。但是,减去线程安全性,你可以看到我想要的解决方案。

要明确的是,我需要修复的问题是,如果我只是在主线程中执行保存,它会阻塞UI一段不可接受的时间,我想将保存移动到后台线程。

所以,问题:

  1. 在保存期间更改对象ID的原因是什么,Core Data能够将它们解析为同一个对象?这是解决这个问题的正确方法吗?
  2. 其他任何好方法吗?

2 个答案:

答案 0 :(得分:2)

简单地说,您无法将保存移动到后台线程。更改与NSManagedObjectContext相关,因此对另一个帖子的NSManagedObjectContext不可见。

我建议对你的存档进行分析,以找出他们为什么花这么长时间。也许更频繁地制作它们或找出可能导致性能问题的其他因素。

您正在使用SQLite商店吗?

更新

如果你正在使用Binary,那肯定会成为一个问题,因为我相信我之前提到过你。二进制文件必须100%加载到内存中,因此也必须100%写入磁盘。

答案 1 :(得分:2)

它可能无法解决您的所有麻烦,但有一种方法-[NSManagedObjectContext obtainPermanentIDsForObjects:error:]可用于在将托管对象保存到商店之前获取该对象的永久ID。所以这应该对你最终做的任何同步都有所帮助。