5

我们应用程序中的数据库由嵌套数层的对象组成。出于架构上的原因,我们现在要迁移到这里是不可行的。

每天都有很大一部分数据过期。随着数据库大小的增长,我们的应用程序性能会下降。

因此,我们需要找到一种有效的方法来保持数据库的小型化(至少在这个版本中),我们正在考虑以下方法之一:

  1. 在 applicationWillResignActive 期间,通过遍历根级别的所有对象来删除 NSManagedObjects,对每个对象调用 delete,然后允许删除级联到 3 层“对多”对象。这涉及到最后保存的一个上下文,它将所有这些都提交给数据库。这通常需要 10-20 秒(在 iPhone 4 上)才能删除对象,而 Springboard 在 10 秒时终止该过程。这样做的一个主要缺点是,如果在 10 秒超时之前未完成上下文保存,则不会删除任何内容,并且每次用户运行应用程序时数据库都会继续增长。

  2. 删除 didFinishLaunchingWithOptions 或 applicationDidBecomeActive 或 applicationWillResignActive 内的整个 sqlite 文件。这迫使我们弹出应用程序的视图控制器堆栈的根目录,以避免尝试显示已删除的数据。最大的缺点是应用程序必须下载并解析数据几秒钟,然后用户下次启动应用程序时才能执行任何操作。

  3. 在用户点击 Home 或 Power 按钮后,使用 beginBackgroundTaskWithExpirationHandler 删除 DB 对象。与此相关的未知数使它变得可怕。有人这样做(成功)吗?

  4. 在应用程序运行时逐步删除较小的对象组。这会增加设备上的负载,以至于破坏了 tableview 的平滑度,使它们变得紧张。与删除旧对象并发的 API 调用已经解析的数据量在这里似乎不切实际。

任何关于在 Core Data 中删除对象的最佳实践的想法都将不胜感激!

4

3 回答 3

1

我遇到了这样的情况,我没有时间清理数据。

我解决了将一些关键实体标记为已删除(实体属性)的问题,并在稍后删除它们(和级联)。您不必标记每个已删除的实体,只需标记允许延迟删除的实体,这样 UI 就可以轻松知道是否有任何实体(标记或未标记)即将被删除。听起来很难,但如果您的数据模型足够干净,则不应该如此。

当您的应用程序重新启动时,您可以删除实体并级联 - 如果这不能结束,您将在可能的情况下重新开始删除 - 或者首先迭代并标记所有可删除的实体,可能会“一个接一个地删除它们” ”。这可以在后台完成而不会弄乱 UI(因为 UI 知道可删除的实体)。如果您这样做时遇到性能问题,您可以很容易地逐步处理删除。

“稍后标记并删除”策略对我来说效果很好。

于 2012-07-24T11:51:21.833 回答
1

橙色80,

您应该在从 -applicationDidEnterBackground: 内启动的后台队列中进行级联删除。为避免被终止,您必须使用后台任务 ID。

我在经常搅动的实例 CD 应用程序中使用此策略。总的来说,使用这种策略,用户将永远不会看到删除。

安德鲁

于 2012-07-24T17:04:04.903 回答
0

您可能需要考虑将选项 1 与标记某些要删除的实体结合使用。这样,即使在应用退出时删除没有完成,在启动时(假设你的应用启动还没有花费一些时间)你可以删除标记的实体(比如几秒钟),然后诉诸“轻" 在后台删除,比如没有用户交互(没有移动的表格视图)。当然,这会增加启动应用程序的时间,但我认为考虑到您的情况,这可能是一个可行的选择。

此外,我希望您通过 Core Data 执行批量加载,并且仅根据需要将对象加载到内存中。

快速重新阅读您的问题,我刚刚有了另一个想法……按照#2 的思路……您为什么不尝试将过时的数据迁移到单独的文件,然后当用户退出应用程序时,只删除该文件?迁移这些对象肯定会有开销,但它可能会提供更流畅的用户体验。

于 2012-07-24T04:11:41.780 回答