用于打开存储的模型与用于创建存储的模型不兼容

我在 Xcode 3.2中创建了一个 Core Data 模型,在 Xcode 4.2中升级之后,我添加了 NSManagedObject 子类的一个新实体(参考新实体)。

首先,它看起来很奇怪因为它和原来的不在同一个组里。下面是我的 xcode 4.2的图片(AlkitabDB 是我在 xcode 3.2中创建的,EndeDB 是当前 xcode 版本(4.2)中的新版本:

the new entity do not grouped in xdatamodel

第二件事,我让它保持原样,然后以与第一个实体相同的方式访问第二个实体(新的实体) ,然后出现标题为的错误。

这里有一个错误:

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";
}

我之前就在寻找解决方案,结果发现我应该从模拟器中删除应用程序并重新运行该应用程序,但它没有起作用。 有人知道解决这个问题的办法吗? 请帮帮我。

100637 次浏览

从模拟器中删除应用程序并对您的项目进行清理。这应该能解决这些问题。确保在删除应用程序时没有在调试器中运行,否则它实际上不会正确地删除应用程序。

如果你想确保它消失了,检查这个目录 Users/INSERT_YOUR_USER_HERE/Library/Application Support/iPhone Simulator/为您的应用程序的文件夹下的版本,你正在运行。

注意: 这仅用于开发。对于生产,您需要实现某种类型的迁移。Google 的“核心数据迁移”,轻量级迁移是最简单的。

首先,xcdatamodeld包中应该只包含 xcdatamodel文件。你的子类 没有应该在 xcdatamodeld中。把这些搬出去。他们很有可能混淆了编译器。

其次,该错误表明 Core Data 无法找到您的模型。您是否创建了数据并接触了模型?如果是这样,那么您处于一种不一致的状态,需要通过删除数据(Philippe 建议的)或者通过滚动模型 回来的更改来解决这个问题。

我得到了错误,但我得到错误的原因是因为以下。

我最初有一个名为“ Entry”的实体,并在数据库中为该实体保存了一行。然后,我添加了另一个名为“ Person”的实体,在添加该实体后,开始构建并得到错误。所以我解决了这个问题,删除“ Person”Entity,然后构建应用程序,删除“ Entry”中的行,然后关闭应用程序。然后我把这个应用程序从我的手机上完全删除了,然后重建了一下,它工作得很好。不确定哪一步纠正了问题(删除行或应用程序) ,但希望如果您正在寻找解决方案,这将有所帮助。:)

编辑: 哦,如果您担心删除您的新实体(在我的情况下“人”) ,以建立应用程序再次记住,您可以得到它回来后,使用 CMD + Z!

每次更改核心日期定义时,都应该删除安装在物理设备或模拟器上的应用程序。

是的。只要删除物理设备上的应用程序并重建它就可以工作了。

我刚刚花了几天时间来对付这个错误,以及合并 ModelFromBundles 崩溃,并得到了“ Can’t merge model with two different tity name *”错误。

原来根本问题在于 Xcode 没有从设备中删除旧资源,而且我的数据模型有旧版本(。妈妈档案)导致了冲突。这就是为什么删除应用程序修复了我的一个设备上的问题。

在通过另一个答案找到 这篇博文之后,我通过改变这条寻找 ALL 的线,使我的应用程序对旧型号更加宽容。妈妈档案:

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];

我使用 这样的问题中的 资源类型: 通过记录所有。应用程序中的妈妈文件:

NSArray *momPaths = [self recursivePathsForResourcesOfType:@"mom" inDirectory:[[NSBundle mainBundle] resourcePath]];
NSLog(@"All .mom files:%@",momPaths);

我还使用 IExplorer查看无关的.Mom 文件(我还没有尝试删除它们)。

下面的方法也很有帮助。它显示一个实体位于[ psc management edObjectModel ]返回的合并模型中,该实体在我的任何模型中或存储本身中都不再存在。这就是让我相信一个旧的模型被缓存在设备本身,干净的建筑没有删除。该方法记录与模型相同、已更改、已添加或已从模型中删除的每个实体。(以 这么回答为起点编写) :

- (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;
}

在将每个存储添加到 NSPerst 存储协调器之前调用:

    [self comparePersistentStore:self.psc withStoreURL:self.iCloudStoreURL];
_iCloudStore = [self.psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:self.iCloudStoreURL
options:options
error:&localError];

我只是删除 [Simulator App Folder]/Document/*.sqlite文件后,在实体的变化和它的工作。 当然,. sqlite 文件包含所有将丢失的存储数据和结构。

在模拟器中尝试“重置内容和设置”。在删除应用程序和清除构建后对我有效

虽然有时候在托管对象模型中更改模式时可以直接从设备中删除应用程序,但在某些情况下这是不可能的,例如,因为您已经使用旧模式发布了应用程序。

如果是这种情况,您必须注意将旧数据迁移到新模式:

核心数据模型版本化与数据迁移

我有这个问题-我首先重置我的模拟器,然后清理项目和重建。然后就成功了。

您需要使用迁移来迁移核心数据模型。无论何时更改模型,都会使其在没有版本控制的情况下不兼容。系好安全带,这个话题有点棘手。

Http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/coredataversioning/articles/introduction.html

如果对 Core Data 模型进行更改,则必须提供一个迁移策略,该策略告诉 Core Data 如何将现有的持久化对象(用户使用当前发布的版本创建的对象)接受到新模型。

对于某些场景,CoreData 能够自动推断从旧模型到新模型的映射。对于更复杂的更改,您可能必须实现一些执行迁移的逻辑。

详细信息可以在 核心数据模型版本化和数据迁移编程指南中找到。

更新
Stack Overflow 上的这个答案涵盖了 Core Data 轻量级迁移的基础知识,并且还有一些代码可以帮助您入门。

解答: 从模拟器中删除应用程序,执行清理并重新构建您的项目。

注意: 每当您执行对核心数据定义的更改时,删除安装在物理设备或模拟器上的应用程序,清理项目并重新构建。

删除应用程序有时并非如此!建议,你的应用程序已经发布了!您不能只是向数据库添加新的实体然后继续——您需要执行迁移!

对于那些不想深入研究文档并寻找快速解决方案的人:

  1. 打开.xcdatamodeld 文件
  2. 点击编辑器
  3. 选择添加模型版本..。
  4. 添加模型的新版本(添加的新数据模型组)
  5. 选择主文件,打开文件检查器(右侧面板)
  6. 并在 Versioned core data model下为当前数据模型选择新版本的数据模型
  7. 这还不是全部)你应该执行所谓的“光迁移”。
  8. 转到您的 AppDelegate并找到 persistentStoreCoordinator被创建的位置
  9. 找到这条线 if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
  10. @{NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES}替换 nil选项(实际上是在该方法的注释代码中提供的)
  11. 给你,玩得开心!

附言。这只适用于轻量级迁移。要使您的迁移符合轻量级迁移的标准,您的更改必须受到限制 到这个狭窄的区域:

  • 添加或删除属性(属性或关系)。
  • 使非可选属性成为可选属性。
  • 使可选属性成为非可选属性,只要提供默认值。
  • 添加或删除实体。
  • 重命名属性。
  • 重命名实体。

为了 Swift 4

coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true])

此问题通常是由于 数据库所在版本之间的不兼容性已创建而发生的。解决这个问题的一般方法是 删除应用程序并重新安装吧。但是在您提到的情况下,DB 的版本在 Xcode 3.2和4.2上是完全不同的。因此,对于 DB,最好使用相同版本的 Xcode。

当您更改核心数据(向表中添加字段、删除字段等)时,应用程序文档文件夹中的 sqlite 文件需要与模式同步。

默认情况下,此文件不会被覆盖,需要重新生成此文件。

遵循以下步骤:

  1. 转到 NSURL 指向的文件夹(此路径可以在应用程序崩溃前生成的异常消息中找到) 示例:/Users//Library/Application Support/iPhone Simulator//Applications//Document

  2. 删除或重命名 sqlite 文件

  3. 清理并重新运行应用程序
  4. 重新运行应用程序将生成一个新的 sqlite 文件。

这将确保模式和 Xcode 是同步的。

只需添加 选择属性,同时在 AppDeliate.m 文件中为核心数据方法创建恒久存储协调器,如下所示

目的 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;
}

SWIFT

    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
}

它解决了我的问题. 。

我的应用程序也遇到了同样的问题(应用程序商店还没有发布)。

我是这么解决的:

  1. 运行干净(Cmd + Shift + K)
  2. 重启 iOS 模拟器
  3. IOS 模拟器-> 重置内容和设置(从导航栏)

(3)是最终使它正常运行的步骤。希望这有所帮助!

请从模拟器中删除应用程序,清除代码并运行。它的工作很好。它可能会帮助你。

如果你正在使用 Swift。

按照@Stas 的回答,然后在应用程序代理中插入选项(而不是 nil) :

let myOptions = [NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true]
if coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: myOptions, error: &error) == nil {
  1. 停止运行应用程序。
  2. 删除模拟器上的应用程序。
  3. - > Clean
  4. 构建,运行。

IOS 模拟器-> 重置内容和设置..。

对我有用

IOS 模拟器-> 重置内容和设置...-> 重置 也可以在 iOS9(xcode 7.1)上工作

我在 Swift 2.1和 Xcode 7中使用的最简单的解决方案是:

  1. 从模拟器中删除应用程序(Cmd + Shift + H 转到主屏幕。长按应用程序,点击交叉,只是通常的方式,你删除一个应用程序从你的手机)

  2. Cmd + Shift + H 再次停止跳舞的应用程序

  3. 返回到您的项目并重新运行

我有这个问题,当写/读从核心数据与2个实体设置。删除应用程序并重新运行程序修复了问题

对于 Swift,在 AppGenerate.swift 中找到这条线

try coordinator!.addPersistentStoreWithType(NSXMLStoreType, configuration:  nil, URL: url, options: nil )

然后换成

try coordinator!.addPersistentStoreWithType(NSXMLStoreType, configuration: nil, URL: url, options: [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true])

对于 Mac 应用程序开发:

  1. 清理项目
  2. 清除派生数据
  3. 转到/Users/YOUR _ NAME/Library/Container/YOUR _ APP _ BUNDLE _ ID/Data/Document/并删除其中的所有文件(例如“ . sqlite”,“ . sqlite-shm”...)

对我很有用,希望这个能帮上忙。

在我的例子中,我有两个持久存储,一个本地存储用于用户特定数据,一个 CoreData + CloudKit 存储用于自动与 iCloud 同步的常见数据。因此,数据模型有两个配置,并且根据需要将实体分配给这两个配置。
由于开发过程中的一个 bug,我试图存储一个不再分配给任何配置的实体。因此,当保存上下文时,CoreData 意识到了不兼容性,并因此错误而崩溃。
当然,在这种情况下,删除应用程序没有任何帮助。必须确保只有分配的实体存储在持久性存储中。

这可能会帮助一些人,但可能不会回答这个问题。在我的例子中,问题得到了解决,因为我忘记将模型添加到正确的配置中。请看附件中的截图。所有模型都添加到默认配置中,但是我的应用程序使用私有配置。将模型从默认配置拖放到正确的配置。

enter image description here