【问题标题】:Background saving with Core Data?使用 Core Data 进行后台保存?
【发布时间】:2011-01-09 13:35:52
【问题描述】:

我有一个基于 Core Data 的 iPhone 应用程序,需要在终止时保存 1000 个托管对象。这需要 8 秒以上的时间,但是,如果应用程序未在大约 10 秒内完成,操作系统会终止应用程序。 6 秒。

我不想提前保存对象,因为这样用户必须再等待 8 秒才能显示结果。

是否有可能以某种方式在后台线程中更早地保存对象,同时仍然可以(只读)访问主线程中的 NSManagedObjectContext 以显示数据?或者是否有可能复制托管对象,并将副本传递给后台线程进行保存?

为了澄清,下面是应用程序中现在发生的情况:我有一个后台线程,它在大约 1 秒内导入 1000 多个对象。如果我在导入时保存,则需要超过 1 秒的时间。因此,为了以最小的延迟显示这些项目,上下文在不保存到主线程的情况下被移交,并且用户尽可能快地得到他的结果。

我现在遇到了如何保存这些对象而无需用户等待 8 秒的问题。如果我在移交之前保存在后台线程中,则用户必须等待。如果我移交后保存在前台线程中,则用户必须等待。我现在能看到的唯一两种可能的方法是:

  1. 以某种方式让核心数据在后台执行其 sqlite 访问,同时仍保持主线程处于响应状态
  2. 将未保存的对象从一个上下文传递到另一个上下文,并保存在后台线程中

这两种方法似乎都是不可能的(至少根据 Core Data 文档)。那么除了让用户等待更长时间(并且可能显示一个漂亮的旋转沙漏:-)之外没有其他解决方案吗?

问候, 乔辰

【问题讨论】:

    标签: performance multithreading core-data


    【解决方案1】:

    是的,有一种方法可以从后台线程中保存托管对象上下文,或者更准确地说,通常称为“在后台线程中导入,并在主线程中显示”。这样,托管对象在导入时会逐个保存,而不是在终止时一次保存。

    我刚刚在SO 就类似问题写了一个简短的答案,但你应该阅读这个Apple doc。 有很多潜在的陷阱,所以要非常非常仔细地阅读。然后阅读Apple's "Efficiently Importing Data"。这也是必读的! Marcus Zarra 的 CoreData book 也很有帮助。

    CoreData 多线程有点棘手,但它确实有回报。祝你好运!

    【讨论】:

    • 同意。在导入时保存它们比在退出时进行大量保存要有效得多。我还在 Mac Developer Network 上做了一个很好的导入演练,甚至解释了如何进行后台保存。
    • 感谢您的帮助。我尝试在导入时保存,结果导入时间增加了。它比最后保存更快,但仍然不够快。我已经澄清了关于这个问题的问题,我当然同意 Core Data 多线程是棘手的......
    • 你的 1. 应该是可以的。只需为每个线程创建一个NSManagedObjectContext。在后台导入时,不要一次创建所有 1000 多个实体并立即保存。相反,在上下文中创建 10 个实体,保存它们,将它们传递给主线程,然后重复此过程。在任何情况下,用户都不能同时看到 1000 多个条目,因此您可以用所有数据都可用的方式欺骗​​您的用户。
    • 谢谢,这就是我现在正在做的事情。我仍然需要从 1000 个条目中计算出一些摘要数据才能显示,因此用户仍然需要等待更长时间。但他同时看到了一些数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-20
    相关资源
    最近更新 更多