iOS coredata 数据库升级 时报Can't find model for source store
在coredata 数据库结构被更改后,没根据要求立即建立新version,而是在原version上进行了小修改,之后才想起来建立新版本。并通过以下代码合并数据库,
NSError *error = nil; NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,NSFileProtectionComplete, NSPersistentStoreFileProtectionKey, nil]; _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); }
结果出现了Can't find model for source store这个 bug。我们先看看stackoverflow上的答案
Your sqlite database's model hash MUST match one of the mom or momd created by your xcdatamodel when you build your app. You can see the hashes in the momd's VersionInfo.plist in the built app's bundle. See below for code to find your database's model hash. So if you change your xcdatamodel instead of creating a new version under Xcode->Editor->Add Model Version... then your model's hash will be different, and addPersistentStoreWithType won't be able to use your old database, which used the old model. That's what causes the "Can't find model for source store" error.
我们根据这个答案去看看bundle 中的version 文件
更改前的截图
再看更改后的截图
注意到 同样的version 6 中的profile model 的hash值不一致,程序会根据这个hash值来判断bundle中有无能在旧数据库上使用的mom文件,如果没有,就会报错。
为什么会crash呢,因为旧版更新为新版后,documents中的数据库是不变的,变化的是bundle中的.momd文件加中的mom文件和version的plist。新版本更新后,会参照新版本中包含的旧版的mom文件来读取旧版本数据库,向新版本迁移。如果旧的mom文件在新版本中更改了,程序就无法读取旧版本数据,就会抛出异常。
解决方法也很简单,找到上个版本使用的xxxx 6.xcdatamodel 文件,替换被错误更改的.xcdatamodel 文件。