用于打开商店的模型与用于创build商店的模型不兼容
我在xcode 3.2中创build了一个Core Data模型,在Xcode 4.2升级后,我添加了一个NSManagedObject子类的新实体(参考新实体)。
首先,它看起来很奇怪,因为它不在旧的那个组中。 这是我的xcode 4.2上的图片(AlkitabDB是我在xcode 3.2中创build的,EndeDB是当前xcode版本(4.2)中的新版本:
第二件事,我放了它,然后我像第一个实体(旧的)一样访问第二个实体(新的实体),并出现标题错误。
这是错误:
2012-01-16 21:13:38.496 iHuria[55953:207] Unresolved error Error Domain=NSCocoaErrorDomain Code=134100 "The operation couldn't be completed. (Cocoa error 134100.)" UserInfo=0x8829cd0 {metadata=<CFBasicHash 0x882a370 [0x1839b38]>{type = immutable dict, count = 7, entries => 2 : <CFString 0x8829b90 [0x1839b38]>{contents = "NSStoreModelVersionIdentifiers"} = <CFArray 0x8829ff0 [0x1839b38]>{type = immutable, count = 0, values = ()} 4 : <CFString 0x8829bc0 [0x1839b38]>{contents = "NSPersistenceFrameworkVersion"} = <CFNumber 0x8829770 [0x1839b38]>{value = +320, type = kCFNumberSInt64Type} 6 : <CFString 0x8829bf0 [0x1839b38]>{contents = "NSStoreModelVersionHashes"} = <CFBasicHash 0x882a080 [0x1839b38]>{type = immutable dict, count = 1, entries => 0 : <CFString 0x882a010 [0x1839b38]>{contents = "AlkitabDB"} = <CFData 0x882a030 [0x1839b38]>{length = 32, capacity = 32, bytes = 0xd02ac5f8be6ab0b39add450aca202ac0 ... 3d45d462998d2ccd} } 7 : <CFString 0x10e3aa8 [0x1839b38]>{contents = "NSStoreUUID"} = <CFString 0x8829e60 [0x1839b38]>{contents = "4F2EE7FF-463B-4055-BBED-8E603CDBDF59"} 8 : <CFString 0x10e3948 [0x1839b38]>{contents = "NSStoreType"} = <CFString 0x10e3958 [0x1839b38]>{contents = "SQLite"} 9 : <CFString 0x8829c40 [0x1839b38]>{contents = "NSStoreModelVersionHashesVersion"} = <CFNumber 0x6b1c7c0 [0x1839b38]>{value = +3, type = kCFNumberSInt32Type} 10 : <CFString 0x8829c70 [0x1839b38]>{contents = "_NSAutoVacuumLevel"} = <CFString 0x882a0c0 [0x1839b38]>{contents = "2"} } , reason=The model used to open the store is incompatible with the one used to create the store}, { metadata = { NSPersistenceFrameworkVersion = 320; NSStoreModelVersionHashes = { AlkitabDB = <d02ac5f8 be6ab0b3 9add450a ca202ac0 ebd1e860 cbb578c2 3d45d462 998d2ccd>; }; NSStoreModelVersionHashesVersion = 3; NSStoreModelVersionIdentifiers = ( ); NSStoreType = SQLite; NSStoreUUID = "4F2EE7FF-463B-4055-BBED-8E603CDBDF59"; "_NSAutoVacuumLevel" = 2; }; reason = "The model used to open the store is incompatible with the one used to create the store"; }
我之前find了解决scheme,发现我应该从模拟器中删除应用程序,然后重新运行应用程序,但它不起作用。 有谁知道这个问题的解决scheme? 请帮忙。
从模拟器中删除应用程序,并执行清理您的项目。 这应该解决这些问题。 确保在删除应用程序时没有在debugging器中运行,否则将不会正确删除它。
如果你想确定它已经没有了,请在你运行的版本下检查这个目录Users/INSERT_YOUR_USER_HERE/Library/Application Support/iPhone Simulator/
你的应用程序的文件夹。
注意:这仅用于开发。 为了生产,你需要实施某种迁移。 谷歌的“核心数据迁移”,轻量级迁移是最简单的。
删除应用程序有时并非如此! build议,你的应用已经发布! 您不能只是将新的实体添加到数据库中,然后继续 – 您需要执行迁移!
对于那些不想深入查看文档并正在寻求快速修复的人:
- 打开你的.xcdatamodeld文件
- 点击编辑器
- select添加模型版本…
- 添加您的模型的新版本(添加新的数据模型组)
- select主文件,打开文件检查器(右侧面板)
- 并在
Versioned core data model
下为当前数据模型select新版本的数据模型 - 这不是全部)你应该执行所谓的“光线迁移”。
- 转到您的
AppDelegate
并find正在创buildpersistentStoreCoordinator
位置 - find这一行
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
- 用
@{NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES}
replacenil
选项(实际上在该方法的注释代码中提供) - 在这里,你去,玩得开心!
PS这仅适用于轻量级迁移。 为了使您的迁移符合轻量级迁移的要求,您的更改必须仅限于这个窄带:
- 添加或删除一个属性(属性或关系)。
- 使非可选属性可选。
- 只要您提供一个默认值,就可以select非自选属性。
- 添加或删除一个实体。
- 重命名一个属性。
- 重命名一个实体。
答案:从模拟器中删除应用程序,执行清理并重新构build您的项目。
注意:每当您对Core Data定义进行更改时,请删除安装在物理设备或模拟器上的应用程序,再次清理项目并重新构build。
如下所示,在AppDelegate.m文件中为核心数据方法创buildpersistentStoreCoordinator时,只需添加选项属性即可
Objective-C的
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (_persistentStoreCoordinator != nil) { return _persistentStoreCoordinator; } NSLog(@"persistentStoreCoordinator___"); NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"MyApp.sqlite"]; NSMutableDictionary *options = [[NSMutableDictionary alloc] init]; [options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption]; [options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption]; NSError *error = 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(); } NSLog(@"persistentStoreCoordinator___2"); return _persistentStoreCoordinator; }
迅速
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = { // The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail. // Create the coordinator and store let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel) let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite") var failureReason = "There was an error creating or loading the application's saved data." // MAIN LINE OF CODE TO ADD let mOptions = [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true] do { try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: mOptions) } catch { // Report any error we got. var dict = [String: AnyObject]() dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data" dict[NSLocalizedFailureReasonErrorKey] = failureReason dict[NSUnderlyingErrorKey] = error as NSError let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict) // Replace this with code to handle the error appropriately. // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)") abort() } return coordinator }
它解决了我的问题..
是。 一旦你删除物理设备上的应用程序,并重build它的作品。
对于swift,在AppDelegate.swift中find这一行
try coordinator!.addPersistentStoreWithType(NSXMLStoreType, configuration: nil, URL: url, options: nil )
并用其replace
try coordinator!.addPersistentStoreWithType(NSXMLStoreType, configuration: nil, URL: url, options: [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true])
每次更改“核心date”定义时,都应该删除安装在物理设备或模拟器上的应用程序。
我只是花了好几天的时间来对付这个错误,还有mergedModelFromBundles崩溃,并且得到了“不能合并两个不同实体的模型名为*”的错误。
事实certificate,根本的问题是,Xcode不会从设备中删除旧的资源,我的旧版本的数据模型(.mom文件)会导致冲突。 这就是为什么删除应用程序解决了我的一个设备上的问题。
通过另一个SO的答案find这篇博文后 ,我通过改变这个查找所有.mom文件的行来让我的应用程序更加容忍旧的模型:
NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
对此,它只在Filters目录中看起来:
NSString *path = [[NSBundle mainBundle] pathForResource:@"Filters" ofType:@"momd"]; NSURL *momURL = [NSURL fileURLWithPath:path]; NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];
我使用recursivePathsForResourcesOfType从这个问题 :帮助解决这个问题,通过logging应用程序中的所有.mom文件:
NSArray *momPaths = [self recursivePathsForResourcesOfType:@"mom" inDirectory:[[NSBundle mainBundle] resourcePath]]; NSLog(@"All .mom files:%@",momPaths);
我也用iExplorer来看看无关的.mom文件(我没有尝试删除它们)。
下面的方法也是有帮助的。 它显示一个实体在[psc managedObjectModel]返回的合并模型中,在我的任何模型或商店本身中都不存在。 这就是让我相信一个旧模型被caching在设备本身,清洁的build筑没有删除。 该方法logging每个相同,已被更改或添加到模型或从模型中移除的实体。 (用这个SO回答作为起点):
- (BOOL)comparePersistentStore:(NSPersistentStoreCoordinator *)psc withStoreURL: (NSURL *)storeURL { NSError *error = nil; // Get the entities & keys from the persistent store coordinator NSManagedObjectModel *pscModel = [psc managedObjectModel]; NSDictionary *pscEntities = [pscModel entitiesByName]; NSSet *pscKeys = [NSSet setWithArray:[pscEntities allKeys]]; //NSLog(@"psc model:%@", pscModel); //NSLog(@"psc keys:%@", pscKeys); NSLog(@"psc contains %d entities", [pscModel.entities count]); // Get the entity hashes from the storeURL NSDictionary *storeMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType URL:storeURL error:&error]; NSDictionary *storeHashes = [storeMetadata objectForKey:@"NSStoreModelVersionHashes"]; //NSLog(@"store metadata:%@", sourceMetadata); NSLog(@"store URL:%@", storeURL); NSLog(@"store NSStoreUUID:%@", [storeMetadata objectForKey:@"NSStoreUUID"]); NSLog(@"store NSStoreType:%@", [storeMetadata objectForKey:@"NSStoreType"]); NSSet *storeKeys = [NSSet setWithArray:[storeHashes allKeys]]; // Determine store entities that were added, removed, and in common (to/with psc) NSMutableSet *addedEntities = [NSMutableSet setWithSet:pscKeys]; NSMutableSet *removedEntities = [NSMutableSet setWithSet:storeKeys]; NSMutableSet *commonEntities = [NSMutableSet setWithSet:pscKeys]; NSMutableSet *changedEntities = [NSMutableSet new]; [addedEntities minusSet:storeKeys]; [removedEntities minusSet:pscKeys]; [commonEntities minusSet:removedEntities]; [commonEntities minusSet:addedEntities]; // Determine entities that have changed (with different hashes) [commonEntities enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) { NSData *storeHash = [storeHashes objectForKey:key]; NSEntityDescription *pscDescrip = [pscEntities objectForKey:key]; if ( ! [pscDescrip.versionHash isEqualToData:storeHash]) { if (storeHash != nil && pscDescrip.versionHash != nil) { [changedEntities addObject:key]; } } }]; // Remove changed entities from common list [commonEntities minusSet:changedEntities]; if ([commonEntities count] > 0) { NSLog(@"Common entities:"); [commonEntities enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) { NSData *storeHash = [storeHashes objectForKey:key]; NSEntityDescription *pscDescrip = [pscEntities objectForKey:key]; NSLog(@"\t%@:\t%@", key, pscDescrip.versionHash); }]; } if ([changedEntities count] > 0) { NSLog(@"Changed entities:"); [changedEntities enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) { NSData *storeHash = [storeHashes objectForKey:key]; NSEntityDescription *pscDescrip = [pscEntities objectForKey:key]; NSLog(@"\tpsc %@:\t%@", key, pscDescrip.versionHash); NSLog(@"\tstore %@:\t%@", key, storeHash); }]; } if ([addedEntities count] > 0) { NSLog(@"Added entities to psc model (not in store):"); [addedEntities enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) { NSEntityDescription *pscDescrip = [pscEntities objectForKey:key]; NSLog(@"\t%@:\t%@", key, pscDescrip.versionHash); }]; } if ([removedEntities count] > 0) { NSLog(@"Removed entities from psc model (exist in store):"); [removedEntities enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) { NSData *storeHash = [storeHashes objectForKey:key]; NSLog(@"\t%@:\t%@", key, storeHash); }]; } BOOL pscCompatibile = [pscModel isConfiguration:nil compatibleWithStoreMetadata:storeMetadata]; NSLog(@"Migration needed? %@", pscCompatibile?@"no":@"yes"); return pscCompatibile; }
用法:在将每个商店添加到NSPersistentStoreCoordinator之前调用:
[self comparePersistentStore:self.psc withStoreURL:self.iCloudStoreURL]; _iCloudStore = [self.psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:self.iCloudStoreURL options:options error:&localError];
- 停止运行应用程序。
- 在模拟器上删除应用程序。
-
Product
– >Clean
- build立,运行。
在Swift 2.1,Xcode 7中为我工作的最简单的解决scheme是:
-
从模拟器中删除应用程序(Cmd + Shift + H进入主屏幕。长按应用程序,点击十字,只是通常的方式从手机中删除一个应用程序)
-
Cmd + Shift + H再次停止应用程序的跳舞
-
回到你的项目并重新运行
从Core Data写入/读取2个实体时,我遇到了这个问题。 删除应用程序并重新运行程序解决了问题
我刚刚删除了[Simulator App Folder]/Document/*.sqlite
文件中进行实体更改后,它的工作。 当然,.sqlite文件包含了所有丢失的数据和结构。
请从模拟器中删除一个应用程序,然后清理一个代码并运行,它可以正常工作。
如果你正在使用Swift。
按照@Stas的回答,在App Delegate中插入选项,代替nil:
let myOptions = [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true] if coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: myOptions, error: &error) == nil {
尝试模拟器中的“重置内容和设置”。 删除应用程序和清理版本后为我工作
我遇到了与我的应用程序相同的问题(尚未在App Store中发布)。
这是我如何解决它:
- 运行清理(Cmd + Shift + K)
- 重新启动iOS模拟器
- iOS模拟器 – >重置内容和设置(从导航栏)
(3)是最终正确运行的步骤。 希望这可以帮助!
尽pipe有时你可以在更改托pipe对象模型中的模式时从应用程序中删除应用程序,但在某些情况下,这是不可能的,例如,因为您已经使用旧模式发布了应用程序。
如果是这种情况,则必须注意将旧数据迁移到新模式:
核心数据模型版本和数据迁移
您将需要使用迁移迁移核心数据模型。 任何时候你改变模型,你都会使它不兼容,没有版本。 把自己绑起来,这是一个有趣的话题。
如果对Core Data模型进行了更改,则必须提供一个迁移策略,告诉Core Data如何将现有持久对象(您的用户使用当前发布的版本创build的对象)应用于新模型。
对于某些情况,核心数据能够自动推断从旧模型到新模型的映射。 对于更复杂的更改,您可能需要执行一些执行迁移的逻辑。
详细信息可以在“ 核心数据模型版本控制和数据迁移编程指南”中find 。
更新
Stack Overflow的这个答案涵盖了Core Data的轻量级迁移的基础知识,也有一些代码可以帮助你开始。
由于在其上创build了数据库的版本之间不兼容,通常会发生此问题。 解决这个问题的一般方法是删除应用程序并重新安装 。 但在你提到的情况下,在Xcode 3.2和4.2上DB的版本是完全不同的。 所以最好使用相同版本的Xcode for DB。
首先,应该在xcdatamodeld
包中唯一的东西是xcdatamodel
文件。 你的子类不应该在xcdatamodeld
。 把他们移出去 他们混淆编译器是有一定的机会的。
其次,错误表示核心数据找不到您的模型。 你有没有创build数据,然后触摸模型? 如果是这样,您处于不一致的状态,需要通过删除数据(Philippebuild议)或滚动模型BACK的更改来修复。
我得到的错误,但我得到错误的原因是因为以下。
我原本有一个名为“Entry”的实体,并为该实体在数据库中保存了一行。 然后我添加了另一个名为“Person”的实体,并添加后,去build立和得到的错误。 所以我通过删除“Person”实体,然后构build应用程序,删除“Entry”中的行,然后closures应用程序来解决问题。 然后我删除了完全closures我的手机的应用程序,然后做了重build,它工作正常。 不知道哪一步纠正了问题(删除行或应用程序),但希望如果你正在寻找一个解决scheme,这将有所帮助。 🙂
编辑:哦,如果你担心删除你的新实体(在我的情况下“人”)再次build立应用程序记得你可以通过使用CMD + Z回来!
我有这个问题 – 我首先重置我的模拟器,然后清理项目和重build。 然后它工作。
当你改变核心数据,(添加一个字段到表,删除字段等),应用程序文档文件夹中的sqlite文件需要与您的模式同步。
这个文件默认不会被覆盖,这个文件需要重新生成。
按着这些次序:
-
转到NSURL指向的文件夹。 (这个path可以在崩溃之前由应用程序生成的exception消息中find)。例子:/用户/图书馆/应用程序支持/ iPhone模拟器//应用程序//文档
-
删除或重命名sqlite文件
- 清理并重新运行应用程序
- 重新运行的应用程序会生成一个新的sqlite文件。
这将确保架构和Xcode同步。
iOS模拟器 – >重置内容和设置…
为我工作
iOS模拟器 – >重置内容和设置… – >在iOS9(xcode 7.1)上重置也可以