在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值不一致,这样就会crash。
为什么会crash呢,因为旧版更新为新版后,documents中的数据库是不变的,变化的是bundle中的.momd文件加中的mom文件和version的plist。新版本更新后,依旧会保留旧版本的mom文件,并参照这个mom文件来读取旧版本数据库,和新版本数据库进行合并。如果旧的版本使用的mom文件在新版本中更改了,程序就无法读取旧版本数据,就会抛出异常。
解决方法也很简单,找到上个版本使用的xxxx 6.xcdatamodel 文件,替换被错误更改的.xcdatamodel 文件。
iOS coredata 数据库升级 时报Can't find model for source store
时间: 2024-10-10 21:14:55