8

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

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

然而,似乎依赖于一个事实,即大的物体应用不同的映射。 在我的情况下,所有的对象基本上都是相同的,并且必须将相同的映射应用于它们中的每一个。在这种情况下,我看不出如何运用他们的技术。

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

回答

2

我在猜测,除了将数据拉出blob之外,还有一些更改需要进行。我的建议是在几个阶段进行迁移。我在这里大声思考,所以有可能改善这一点。这需要你使用SQLite。

为了使这项工作,你将有你的模型的三个版本:

  1. 的原始模型
  2. 去除(并且可能与一种特殊的唯一的ID added--属性模型见下文)
  3. 所有的替代属性

之所以这样做,你所做的更改,包括增加新的实体和关系模型是,TRA从版本1到版本2的应用程序应该可以通过自动轻量级迁移来实现。在这种情况下,核心数据不需要将任何内容加载到内存中 - 它只是发出SQL语句直接在数据库上进行更改。

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

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

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

保存数据并关闭商店。

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

很简单吧?

+0

谢谢雅克,实际上这给了我一个很好的提示,我做了类似的事情,没有像SQLite那么低。但是我为自己创建了两个不同的商店并在其中创建了对象。棘手的部分是确保Core Data尽快将对象转换为故障。 – Kamchatka 2011-01-14 06:40:03