核心数据推断迁移 - 自动“轻量级”与手动

时间:2010-03-29 01:40:45

标签: iphone objective-c core-data migration mapping-model

我已经以一些简单的方式更新了现有iPhone应用程序的模型(删除属性,添加属性,删除索引),并且可以使用自动轻量级迁移来迁移持久性存储。

由于数据集的典型大小,处理时间并不重要,并且需要为用户提供反馈。

NSMigrationManager提供了一个简单但有用的migrationProgress值,可在执行迁移时发送KVO通知。这构成了提供反馈的基础,但是尝试使用推断模型([NSMappingModel inferredMappingModelForSourceModel:destinationModel:error:])会导致完全相同的数据集的时间截然不同。

原始iPhone上的配置文件结果(2G),磁盘上的缓存大小:1.785 MB。

自动推断轻量级迁移

PROFILE: CacheManager -migrateStore
PROFILE:   0.6130 (+0.6130) models loaded
PROFILE:   1.1759 (+0.5629) delegate -CacheManagerWillMigrate:
PROFILE:   1.2516 (+0.0757) persistent store coordinator loaded
PROFILE:   5.1436 (+3.8920) automatic lightweight migration completed
PROFILE:   5.5435 (+0.3999) delegate -CacheManagerDidFinishMigration:withError:

手动推断迁移

PROFILE: CacheManager -migrateStore
PROFILE:   0.6660 (+0.6660) models loaded
PROFILE:   1.1471 (+0.4811) inferred mapping model generated
PROFILE:   1.4046 (+0.2574) delegate -CacheManagerWillMigrate:
PROFILE:   1.5058 (+0.1013) persistent store coordinator loaded
PROFILE:   22.6952 (+21.1894) manual migration completed
PROFILE:   23.1478 (+0.4525) delegate -CacheManagerDidFinishMigration:withError:

因此,使用推断模型,手动迁移所需的时间比自动迁移长5倍!


更新:模型加载

NSPersistentStoreCoordinator "Migration Options"的核心数据文档说:

  

NSInferMappingModelAutomaticallyOption

     

......协调员将尝试   如果没有,则推断映射模型   找到。

这就是XCode构建,编译和安装的原因。必须删除捆绑映射模型(或者只是取消目标)以允许推断轻量级迁移。


这是一个很大的不一致性,轻量级选项NSPersistentStoreCoordinator -addPersistentStoreWithType:configuration:URL:options:error:在处理时绝对没有提供进展的迹象。

任何人都可以提供一种支持的方式来在自动迁移期间获取migrationProgress值, OR 是一种在手动处理过程中将推断的映射模型配置为与自动一样快的方法吗?


更新:错误报告

向WWDC的工程师发表讲话,他们要求提供错误报告,要求migrationProgress进行自动轻量级迁移处理。

如果更新API以添加进度报告,我将再次更新..

2 个答案:

答案 0 :(得分:3)

目前,Core Data使用私有类NSSQLiteInPlaceMigrationManager来执行轻量级迁移。这是NSMigrationManager的子类,但在migrateStoreFromURL:type:options:withMappingModel:toDestinationURL:destinationType:destinationOptions:error:中处理所有内容。从它的外观来看,这个类实际上是直接在SQLite存储上执行更改,而不是根据手动迁移的需要将所有内容都拉入内存。

这解释了为什么您看到轻量级迁移完成得更快。

不幸的是,即使您使用了在幕后使用的私有API的这些知识,它也不会为获得进度指示而获得太多收益。 NSSQLiteInPlaceMigrationManager的进度值目前从未改变,它始终为零。 currentEntityMapping的值似乎仍为零。

在Apple提供API之前,似乎我们运气不好。你有雷达号码,所以我可以打开副本吗?

答案 1 :(得分:2)

当您自己定义映射模型而不是使用推断模型时会发生什么?听起来像推断模型的创建会导致性能损失,直接定义映射模型并将其包含在项目中会解决。

更新

  

我已经尝试过这种策略,并且使用在XCode中生成的映射模型产生的处理时间与推断的运行时模型大致相同。唯一真正的区别是从捆绑中加载模型的时间比在运行时推断时稍快。此外,一旦映射模型捆绑在应用程序中,自动迁移就不再是轻量级的,我假设它使用的是捆绑模型。从目标中删除映射模型会使处理时间回到~4秒,以实现自动轻量级

这当然是违反直觉的。您的项目是否足够简单,可以作为这种低效率的示例发布,或者您是否有一个隔离此问题的测试项目?在任何一种情况下,看看它都是非常有帮助的,这样我们就可以A)希望能解开这个谜团;或者B)将其作为Apple的一个相当大的错误提交,因为反过来应该是这样。

您正在使用的数据集有多大?