将二进制数据对象迁移到核心数据实体

时间:2017-01-25 22:47:39

标签: ios objective-c xcode core-data

我有一个使用Core Data来管理我们称之为Entities的{​​{1}}的应用。每个列表都有一个lists属性,其类型为offlineDataBinary Data选项适用于此。

此实体使用以下方法保存自定义对象数组:

Allows External Storage

这会将对象保存到NSArray *customObjects;// My custom objects that have been added self.list.offlineData = [NSKeyedArchiver archivedDataWithRootObject:customObjects]; blob,因为所有对象都在使用Core DatainitWithEncoder:

当用户想要查看列表时,我们会做相反的事情:

encodeWithCoder:

问题

这一开始似乎是一个很好的解决方案(现在显然是愚蠢的),因为我们可以轻松地为对象添加其他属性等。但是我们没有预料到的是用户添加了数千个对象。这导致:

  • 尝试存档或创建数千个对象的数组时出现内存问题和崩溃
  • 取消归档对象时的内存问题
  • 取决于设备速度,取消归档可能需要很长时间,让用户坐下来等待
  • 用户可以添加到列表中的对象数量的限制。
  • 搜索对象时的速度问题,因为我无法执行提取请求。

解决方案吗

我想到的解决方案是将所有自定义对象迁移到NSArray *items = [NSKeyedUnarchiver unarchiveObjectWithData:self.list.offlineData]; 个实体。这将是Core DataTo Many之间的list entity关系。

这似乎可以解决上面列出的问题,但我并不是百分百肯定。

有没有人对此提出建议,如果这是“#34;迁移”的最佳方式?

1 个答案:

答案 0 :(得分:2)

如您所述,迁移到新实体可以很好地解决您的问题。在新的数据模型版本中,您将创建新的列表项实体,删除现有的列表属性,并创建您描述的多对多关系。

尽管如此,你不能依赖自动迁移 - 你需要自定义这个过程。我在a different answer中描述了主要适用于您的过程。您必须创建映射模型和NSEntityMigrationPolicy的自定义子类。它并不复杂,但大多数iOS开发人员都不熟悉。

与其他答案不同,您需要在createDestinationInstances(forSource:, in:, manager:)子类中实现NSEntityMigrationPolicy方法。对于您的实体的实例,您可以在此处创建一组列表项对象。取消归档现有数据blob并创建新实例。

请注意,这意味着您必须取消归档现有列表blob的所有。迁移可能需要一段时间才能完成您描述的方案。但是每个用户只需要做一次。确保在屏幕上显示一些信息,以便人们知道发生了什么,并确保使用足够大的列表来测试迁移。

Apple的docs on custom migrations也可能派上用场。