进行核心数据迁移时内存不足

时间:2010-12-18 17:40:39

标签: iphone multithreading core-data iphone-sdk-3.0 core-data-migration

我正在两个版本的应用程序之间迁移CoreData模型。我在以前的版本中将二进制数据存储为blob,我想将它们从blob中取出以获得性能。我的问题是,在迁移过程中,似乎Core Data将所有内容加载到内存中会导致内存不足警告,然后导致我的应用程序被杀死。

Apple文档建议如下: http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreDataVersioning/Articles/vmCustomizingTheProcess.html#//apple_ref/doc/uid/TP40005510-SW9

但是,它似乎依赖于大对象应用不同映射的事实。 在我的例子中,所有对象基本相同,并且必须对每个对象应用相同的映射。在这种情况下,我没有看到我如何应用他们的技术。

我应该如何使用非常大的对象处理迁移?

1 个答案:

答案 0 :(得分:2)

我猜你除了从blob中提取数据外,你还想做一些改变。我的建议是在几个阶段进行迁移。我在这里大声思考,所以有可能对此有所改进。这要求您使用SQLite。

为了完成这项工作,您将拥有三个版本的模型:

  1. 原始模型
  2. 删除了属性的模型(可能添加了一个特殊的唯一ID - 见下文)
  3. 包含您所做的所有更改的模型,包括添加新实体和替换属性的关系
  4. 这样做的原因是从版本1到2的转换应该可以通过自动轻量级迁移来实现。在这种情况下,Core Data不需要将任何内容加载到内存中 - 它只是发出SQL语句来直接在数据库上进行更改。

    因此,您首先要使用旧的模型版本设置持久性存储协调器。加载数据后,浏览要迁移的所有对象,提取二进制属性,然后以某种方式将其写入磁盘。您可以使用带有批处理和常规自动释放池耗尽的获取请求,以确保不会为临时对象使用太多内存。将数据存储到NSCachesDirectory获得的目录中。您显然希望以一种允许您将其与对象的managedObjectID相关联的方式存储数据。

    然后,关闭所有内容并要求Core Data将商店从版本1迁移到版本2.有关详细信息,请参阅this link。用版本2打开商店。

    您可能必须添加一个步骤,为每个对象分配某种唯一ID,因为我不确定Core Data在进行非轻量级迁移时是否维护对象ID。如果您需要这样做,您的版本2模型会向您正在获取二进制数据的对象添加一个新属性,该二进制数据将是可选的或具有默认值集。由于轻量级迁移不应更改managedObjectID,因此您可以将新唯一ID的映射保存到两段前保存的二进制数据中的managedObjectID。

    保存数据并关闭商店。

    打开商店并从版本2迁移到版本3,这应该基本上是您在发布问题之前编写的代码。商店打开后,添加您从版本1商店保存的所有对象,并使用您在此过程中保存的数据设置关系。

    简单,对吧?