我知道这是一个经常被问到的问题,但是我找到的解决方案似乎都不适用于我。
这是我的情况: 我的应用程序有一个数据模型,我想为它添加版本。所以在XCode中,我做了Design - >数据模型 - >添加模型版本。我还更新了我的委托的persistentStoreCoordinator方法,如下所示:
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory]
stringByAppendingPathComponent: @"foo.sqlite"]];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
nil];
NSError *error = nil;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if(![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
/*Error for store creation should be handled in here*/
}
return persistentStoreCoordinator;
}
为了确保一切仍然有效,我做了一个干净的所有,构建,并在模拟器中测试它。一切都运作到目前为止。
接下来,我选择了新版本数据模型,使用XCode将其设置为当前版本,并为实体添加了一个额外属性。然后,我做了一个干净的所有,构建。现在,每当我启动应用程序时,它都会崩溃并出现此错误:'无法将模型与名为'foo''的两个不同实体合并。
我做错了什么?我已经尝试确保没有向目标添加数据模型,只将当前版本数据模型添加到目标,以及两者。每次我测试我都要确保清理所有。
任何人都可以解释为什么它对我不起作用?
编辑:
这是我的managedObjectModel方法:
- (NSManagedObjectModel *)managedObjectModel {
if (managedObjectModel != nil) {
return managedObjectModel;
}
managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
return managedObjectModel;
}
答案 0 :(得分:5)
我已经预料到了managedObjectModel getter的这种实现。
在您的实现中,捆绑包中的所有模型都合并为一个模型。因此,.momd中的所有版本也会合并,从而导致重复的实体定义。
更改代码以使用适当的模型文件显式初始化模型,它应该可以正常工作。
NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"datamodel" ofType:@"momd"];
NSURL *modelURL = [NSURL fileURLWithPath:modelPath];
managedObjectModel_ = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
答案 1 :(得分:0)
如果您在核心数据上使用Version Models
,则必须初始化为您要使用的版本的版本。在Application Bundle
上,您会找到一个扩展名为.momd
的文件,即完整模型。在此文件中,您会在其中找到大量.mom
个文件,每个.mom
文件代表您模型的一个版本。
如果您运行应用程序并使用.momd文件及其中的所有版本进行初始化,Core Data将创建所有版本,之后我们将拥有 “重复实体” 错误,Core Data不知道使用什么版本。现在,解决问题的唯一方法是删除应用程序,将代码指向正确的.mom
文件并再次运行,因此Core Data只创建一个内部数据库版本。
以下是执行此任务的一段代码:
NSString *fullModelName = @"myModel.momd"; // The name of the main model.
NSString *modelVersionName = @"myModel1.0.mom"; // Only the name of the version.
NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
NSString *modelPath = [NSString stringWithFormat:@"%@/%@/%@", bundlePath, fullModelName, modelVersionName];
//
NSURL *modelURL = [NSURL fileURLWithPath:modelPath];
managedObjectModel_ = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];