迁移大型Core Data数据库崩溃

时间:2013-02-15 16:50:36

标签: ios objective-c xcode core-data

我有一个将产品存储在Core Data文件中的应用程序。这些产品包括图像作为“可转换”数据。 现在我尝试使用轻量级迁移添加一些属性。当我使用小型数据库对其进行测试时,它运行良好但是当我使用一个接近500 MB的非常大的应用程序时,应用程序通常因内存不足而崩溃。有人知道如何解决这个问题吗?

先谢谢!

1 个答案:

答案 0 :(得分:6)

您必须使用其他迁移选项之一。自动轻量级迁移过程非常方便使用。但它的缺点是它会立即将整个数据存储加载到内存中。两个副本,实际上,一个用于迁移之前,一个用于之后。

首先,是否可以重新创建或重新下载这些数据?如果是这样,您可以使用从旧版本到新版本的自定义映射模型。使用自定义映射模型,您可以指示某些属性不会迁移,从而通过丢弃该数据来减少内存问题。然后,当迁移完成后,重新创建或重新下载该数据。

如果情况并非如此...... Apple建议使用多种映射模型的多次传递技术。如果您有多个实体类型对大数据存储大小有贡献,那么它可能会有所帮助。基本上,您最终会在不同的传递中迁移不同的实体类型,因此您可以避免一次性加载所有内容的开销。

如果 不是这种情况(例如,膨胀全部来自同一实体类型的实例),那么,是时候编写自己的自定义迁移代码了。这将涉及设置两个核心数据堆栈,一个包含现有数据,另一个包含新模型。运行现有数据存储,在新存储中创建新对象。如果您批量执行此操作,您将能够控制内存。一般方法是:

  1. 在新模型中创建新实例并仅复制属性。您无法设置关系,因为新数据存储中可能不存在相关对象。保留一个可变字典,将NSManagedObjectID从旧商店映射到新商店,以便在下一步中使用。为了保持低内存使用率:
    • 一旦创建了目标存储对象,就可以使用refreshObject:mergeChangesNO为第二个参数释放源对象的内存。
    • 每10个实例(或50个或其他)保存对目标托管对象上下文的更改,然后reset。间隔是一种平衡行为 - 经常做,你会不必要地放慢速度,做得太少,内存使用量增加。
  2. 执行第二遍,在目标商店中设置关系。对于每个源对象,
    • 使用您创建的对象ID地图查找相应的目标对象
    • 运行源对象的关系。对于每一个,找到相应的目标对象,也使用对象ID映射。
    • 根据结果设置目标对象的关系。
  3. 当你在这里时,请考虑为什么你的数据存储如此之大。您是否在数据存储中存储了一堆二进制数据blob?如果是这样,请确保您在新模型中使用“允许外部存储”选项。