我正在一个应用程序的两个版本之间迁移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

但是,似乎依赖于这样的事实,即对大型对象应用了不同的映射。
就我而言,所有对象基本上都是相同的,并且必须将相同的映射应用于每个对象。在这种情况下,我看不到如何应用他们的技术。

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

最佳答案

我猜您除了要从blob中提取数据之外,还需要进行一系列更改。我的建议是分几个阶段进行迁移。我有点想在这里,因此有可能对此进行改进。这要求您使用SQLite。

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

  • 原始模型
  • 删除了属性的模型(可能添加了特殊的唯一ID,请参见下文)
  • 具有您所做的所有更改的模型,包括添加新实体和替换属性
  • 的关系

    这样做的原因是,从版本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存储中保存的所有对象,并使用在此过程中保存的数据来建立关系。

    简单吧?

    10-08 06:13
    查看更多