iOS 7 - 核心数据迁移 - Xcode 5

时间:2013-11-13 17:16:34

标签: ios iphone objective-c xcode core-data

我在执行CoreData迁移时遇到了一个非常奇怪的问题。

基本上,我有2个实体,其中一个我添加了一个属性,另一个,我将属性类型从NSString更改为NSArray(可转换)。 到目前为止,它非常好,运行良好,在迁移后进行了测试并且数据完整性保持不变。

如果我在Xcode 5上运行完全相同的代码(我不知道它是否与iOS SDK 7.0或Xcode 5相关),则会出现问题,但迁移会运行并破坏数据。

我最终创建了一个简单的项目来演示正在发生的事情。 https://dl.dropboxusercontent.com/u/1393279/CoreDataMigration.zip

重现的步骤是: - 在Xcode 5(iOS SDK 7.0)上,您可以使用模拟器 -

1 - 打开项目“BeforeMigration”并执行。查看创建的日志和数据,到目前为止没问题;

2 - 停止项目;

3 - 打开项目“AfterMigration”,构建并运行。

4 - 看到迁移已执行,但数据已损坏:

  

2013-11-13 12:22:29.778 CoreDataMigration [7223:70b] CoreData:错误:   fetchRowForObjectID期间的异常: * - [NSKeyedUnarchiver   initForReadingWithData:]:难以理解的存档(0x43,0x32,0x0,   0x0,0x0,0x0,0x0,0x0)userInfo为(null)2013-11-13   12:22:29.782 CoreDataMigration [7223:70b] 终止应用程序   未捕获的异常'NSInvalidArgumentException',原因:' **    - [NSKeyedUnarchiver initForReadingWithData:]:难以理解的存档(0x43,0x32,0x0,0x0,0x0,0x0,0x0,0x0)'

AFAIK,难以理解的存档意味着CoreData上的数据已损坏。

很难理解的是,之前的代码完全相同,因此,如果它是一个逻辑问题,它应该发生在Xcode 4.5上。我查找了CoreData Diffs,但没有发现任何相关内容。

如果有人知道可能出现什么问题,我将不胜感激。 感谢。

2 个答案:

答案 0 :(得分:3)

在iOS 7中,Core Data SQLite存储的默认日记模式已更改为预写日志(WAL),以提高可靠性,性能和并发性。

问题在于我没有使用核心数据移动-wal文件。修复它的一种方法是使用:

删除-wal
NSDictionary *options = @{NSSQLitePragmasOption:@{@"journal_mode":@"DELETE"}};

或者移动-wal:

- (NSPersistentStore *)migratePersistentStore:(NSPersistentStore *)store toURL:(NSURL *)URL options:(NSDictionary *)options withType:(NSString *)storeType error:(NSError **)error

答案 1 :(得分:2)

尝试使用moGenerator link并尝试以下步骤:

  • 使用MOGen(或MOGenerator)从每个版本的模型中自动生成核心数据模型实体类(使用专用的预构建目标);
  • 在创建新数据模型时始终启用模型版本控制;
  • 创建数据模型的新版本时:

    1. 添加新的数据模型版本 - 称之为"新版本&#34 ;; 将其核心数据模型标识符设置为下一个所需版本(如:1.1或2.0等)。这是模型版本的逻辑开发人员友好标识符 - 它不会强制Core Data以不同方式处理此版本,除非对其进行重大更改;

    2. 通过将其版本标识符附加到名称来重命名以前的模型版本。例如,如果它是" MyDataModel.xcdatamodel"其版本标识符设置为1.1 - 将其重命名为" MyDataModel_1.1.xcdatamodel";

    3. 将新添加的版本重命名为简单的模型名称,例如" MyDataModel.xcdatamodel"并使其成为当前版本。这样,您始终保持当前模型版本的名称相同,并且您的MOGen激活/构建脚本不会更改(如果您使用MOGen - 您应该这样做);

    4. 根据需要修改当前模型;

    5. 取决于对模型所做更改的规模,Core Data Lightweight Migration功能可以按原样处理。如果更改是夸张的,您可能需要定义自己的映射模型以帮助Core Data将旧数据存储迁移到模型的最新版本中;

    6. 清洁您的产品;

    7. 重建您的产品;

    8. 测试它。

Andrey Kornich的最佳实践