10

我已经以一些简单的方式(删除属性、添加属性、删除索引)更新了现有 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

NSInferMappingModelAutomaticallyOption

...如果找不到映射模型,协调器将尝试推断映射模型。

这就是为什么 XCode 构建、编译和捆绑的映射模型必须被移除(或只是非目标)以允许推断轻量级迁移发生。


这是一个很大的不一致之处,而且轻量级选项NSPersistentStoreCoordinator -addPersistentStoreWithType:configuration:URL:options:error:在处理时绝对不提供进度指示。

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


更新:错误报告

与 WWDC 的工程师交谈,他们要求提供错误报告,要求migrationProgress进行自动轻量级迁移处理。

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

4

2 回答 2

3

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

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

不幸的是,即使您使用这些在幕后使用的私有 API 的知识,也无法获得进度指示。progress 的值目前从未改变过NSSQLiteInPlaceMigrationManager,它始终为零。的值currentEntityMapping似乎也保持为零。

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

于 2012-03-15T16:21:16.313 回答
2

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

更新

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

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

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

于 2010-03-29T05:35:08.907 回答