在 iPhone 上迁移大型 CoreData 数据存储时出现内存问题 [英] Memory issues migrating large CoreData datastores on iPhone

查看:20
本文介绍了在 iPhone 上迁移大型 CoreData 数据存储时出现内存问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序下面有一个可能非常大的 CoreData 数据存储(可能很容易超过 30MB).在使用自动迁移 (addPersistentStoreWithType:configuration:URL:options:error:) 时,我开始注意到内存问题,因此我开始研究迁移存储的较小部分以避免所有 CoreData 的方法一次迁移所有内容时发生的对象堆积.

My app has a potentially very large CoreData datastore underneath it (could easily be upwards of 30MB). I've started noticing memory issues when using the automatic migration (addPersistentStoreWithType:configuration:URL:options:error:) so I started looking into the methods of migrating smaller parts of the store to avoid all the CoreData object buildup that happens when you migrate everything at once.

这在 official文档 在多次通过"部分,但是看起来他们建议的方法是按实体类型划分您的迁移,即制作多个映射模型,每个映射模型从完整数据中迁移实体类型的子集型号.

This is discussed in the official documentation in the "Multiple Passes" section, however it looks like their suggested approach is to divide up your migration by entity type, i.e. make multiple mapping models, each of which migrate a subset of the entity types from the complete data model.

唯一的问题是 - 如果一种实体类型是您的数据存储的主要部分怎么办?按照 Apple 推荐的方法,整个实体类型仍将在一次迁移中完成,并且内存问题可能会持续存在.

The only problem is - what if one entity type is the majority of your datastore? Going by the Apple-recommended approach, that whole entity type is still going to be done in a single migration and the memory issues will presumably persist.

是否有任何技术可用于实际迁移特定类型的实体子集,以保证在尝试全部迁移时不会耗尽内存?

Are there any techniques available to actually migrate a sub-set of entities of a specific type to guarantee that you will not run out of memory when trying to migrate them all?

提前感谢您的帮助.

在进行更多挖掘之后,我发现 Apple 推荐的将数据库拆分为实体类型实际上仅适用于非相关实体(如 在这里讨论过),所以它解决实际数据库问题的可能性比我最初想象的要小写了这篇文章.

After doing more digging, I have discovered that the Apple-recommended split of the DB into entity types actually only works for non-related entities (as discussed here), so it's even less likely to solve the problems of a real-world DB than I thought when I originally wrote this post.

我开始认为实际上通过 NSMigrationManager 完成的 CoreData 迁移现在根本无法扩展,如果您希望能够迁移,基本上不能拥有大于约 20-30MB 的数据库它在当前一代的 iOS 设备上.唯一可行的方法似乎是完全短路所有 NSMigrationManager/NSMappingModel 东西,并在代码中完全自定义迁移.如果真的是这样的话,这似乎是苹果公司的一个巨大疏忽.

I'm starting to think that CoreData migrations that are actually done through NSMigrationManager don't scale at all now and you basically can't have a DB that is bigger than about 20-30MB if you want to be able to migrate it on current generation iOS devices. The only viable approach seems to be to short-circuit all the NSMigrationManager / NSMappingModel stuff completely and write the migration completely custom in code. Seems like a huge oversight on Apple's part if this is actually the case.

推荐答案

我能够通过利用轻量级"迁移在短期内解决这个问题,如 http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreDataVersioning/Articles/vmLightweight.html#//apple_ref/doc/uid/TP40008426-DontLinkElementID_1.

I was able to get around this in the short-term by leveraging "lightweight" migration, as described in http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreDataVersioning/Articles/vmLightweight.html#//apple_ref/doc/uid/TP40008426-DontLinkElementID_1.

诀窍是在您手动调用迁移时提取专门用于 SQLite 存储类型的 NSMigrationManager 子类,如该页面上的最后一个代码示例所示.

The trick is to pull the NSMigrationManager subclass that is specifically for SQLite store types when you're manually invoking the migration, as shown in the last code sample on that page.

虽然这不是通用修复,因为它仅在数据存储中的架构更改足够简单以至于可以进行轻量级迁移的情况下才有效.当您处理非平凡的映射时,仍在等待 Apple 的回复,以了解推荐的解决方案是什么.

This isn't a general-purpose fix though since it only works if the schema change in your datastore is simple enough that lightweight migration is possible. Still waiting to hear back from Apple as to what the recommended solution is when you're dealing with a non-trivial mapping.

这篇关于在 iPhone 上迁移大型 CoreData 数据存储时出现内存问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆