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

标签 ios objective-c xcode core-data

我有一个应用程序使用 Core Data 来管理我们称之为 listsEntities。每个列表都有一个 offlineData 属性,类型为 Binary DataAllows External Storage 选项对此适用。

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

NSArray *customObjects;// My custom objects that have been added
self.list.offlineData = [NSKeyedArchiver archivedDataWithRootObject:customObjects];

这会将对象保存到 Core Data blob,因为所有对象都在使用 initWithEncoder:encodeWithCoder:

当用户想要查看列表时,我们执行相反的操作:

NSArray *items = [NSKeyedUnarchiver unarchiveObjectWithData:self.list.offlineData];

问题

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

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

解决方案?

我想到的解决方案是将所有自定义对象迁移到 Core Data 实体。这将是 list entityobject entity 之间的To Many 关系。

这似乎可以解决上述问题,但我不是 100% 确定。

有没有人对此有建议,这是否是“迁移”的最佳方式?

最佳答案

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

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

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

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

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

关于ios - 将二进制数据对象迁移到核心数据实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41863113/

相关文章:

ios - 当我上下滚动时,UITableView 按钮和标签被删除

ios - 无法在 UICollectionViewController 上平滑滚动以加载大量数据

ios - Xcode 9 的多发布环境 - Swift

ios - 如何使用 UITableViewCell EditingStyle Insert 在单元格上显示 AccessoryView?

ios - Xcode 5 和 phonegap : linker errors on building for device but not for simulator

iOS:NSURLAuthenticationChallenge 是否通过网络发送加密凭据?

objective-c - 从您的应用程序启动 Facetime?

ios - 如何创建对象之间间隔为 5 分钟的时间 NSArray?

ios - 防止 RubyMotion 应用程序旋转

c - Objective-C 字符串,字符串格式化程序