ios 用于开设商店的模型与用于创建商店的模型不兼容

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8881453/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 16:21:01  来源:igfitidea点击:

The model used to open the store is incompatible with the one used to create the store

iosiphonecore-data

提问by dejoong

I created a Core Data model in xcode 3.2 and after upgrading in Xcode 4.2, I then added a new entity of the NSManagedObject subclass (refer to the new entity).

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

First thing, it looks weird because it's not in the same group as the old one. Here is the picture on my xcode 4.2 (AlkitabDB is the one i created in xcode 3.2, EndeDB is the new one from current xcode version(4.2):

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

the new entity do not grouped in xdatamodel

新实体未在 xdatamodel 中分组

Second thing, I let it as it is, then I accessed the second entity (the new one) the same way as the first entity (the old one), and the error as titled appears.

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

Here is the error:

这是错误:

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

I looked for the solution before and discovered that I should remove the appliation from simulator and rerun the app, and it didn't work. Does anyone know a solution for this issue? Please help.

我之前寻找过解决方案,发现我应该从模拟器中删除应用程序并重新运行该应用程序,但它不起作用。有谁知道这个问题的解决方案?请帮忙。

回答by Stas

Deleting the app is sometimes not the case!Suggest, your app has already been published! You can't just add new entity to the data base and go ahead - you need to perform migration!

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

For those who doesn't want to dig into documentation and is searching for a quick fix:

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

  1. Open your .xcdatamodeld file
  2. click on Editor
  3. select Add model version...
  4. Add a new version of your model (the new group of datamodels added)
  5. select the main file, open file inspector (right-hand panel)
  6. and under Versioned core data modelselect your new version of data model for current data model
  7. THAT'S NOT ALL ) You should perform so called "light migration".
  8. Go to your AppDelegateand find where the persistentStoreCoordinatoris being created
  9. Find this line if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
  10. Replace niloptions with @{NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES}(actually provided in the commented code in that method)
  11. Here you go, have fun!
  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. nil选项替换为@{NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES}(实际上在该方法的注释代码中提供)
  11. 给你,玩得开心!

P.S. This only applies for lightweight migration. For your migration to qualify as a lightweight migration, your changes must be confined to this narrow band:

PS 这仅适用于轻量级迁移。要使您的迁移符合轻量级迁移的条件,您的更改必须限制在以下范围内:

  • Add or remove a property (attribute or relationship).
  • Make a nonoptional property optional.
  • Make an optional attribute nonoptional, as long as you provide a default value.
  • Add or remove an entity.
  • Rename a property.
  • Rename an entity.
  • 添加或删除属性(属性或关系)。
  • 将非可选属性设为可选。
  • 只要您提供默认值,就可以将可选属性设为非可选。
  • 添加或删除实体。
  • 重命名属性。
  • 重命名实体。

For Swift 4

对于 Swift 4

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

回答by Philippe Sabourin

Remove the app from the simulator and perform a clean on your project. That should clear those issues up. Make sure that you are not running in the debugger when you delete the app or else it won't actually delete it properly.

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

If you want to be sure its gone, check this directory Users/INSERT_YOUR_USER_HERE/Library/Application Support/iPhone Simulator/for your app's folder, under the version you're running.

如果您想确定它已经消失,请Users/INSERT_YOUR_USER_HERE/Library/Application Support/iPhone Simulator/在您正在运行的版本下检查此目录中的应用程序文件夹。

Note: This is for development only. For production, you need to implement some sort of migration. Google "Core Data Migration", with lightweight migration being the simplest.

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

回答by Dhaval H. Nena

Just add Optionsattribute while creating persistentStoreCoordinator in AppDelegate.m file for the core data method as below

只需在 AppDelegate.m 文件中为核心数据方法创建 persistentStoreCoordinator 时添加Options属性,如下所示

OBJECTIVE-C

目标-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
}

It had solved my problem..

它已经解决了我的问题..

回答by Bhavin

Answer :Remove the app from the Simulator , Perform a Clean and Re-Build your Project.

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

Note :Whenever you perform changes to the Core Data definition, Delete the app installed on the Physical Device or Simulator, Clean the Project and Re-Build again.

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

回答by Ali Asgher Lakkadshaw

For swift, in AppDelegate.swift find the line

对于 swift,在 AppDelegate.swift 中找到该行

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

and replace it with

并将其替换为

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

回答by world-software.net

Yes. Once you delete app on physical device and rebuild it works.

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

回答by Symmetric

I just spent several days fighting this error, as well as mergedModelFromBundles crashes, and getting the "Can't merge models with two different entities named *" error.

我只是花了几天的时间来解决这个错误,以及 mergeModelFromBundles 崩溃,并收到“无法合并具有两个不同实体的模型 *”错误。

It turns out the root problem was that Xcode doesn't remove old resources from devices and I had old versions of my data model (.mom files) that were causing conflicts. This is why deleting the app fixed the problem on one of my devices.

事实证明,根本问题是 Xcode 不会从设备中删除旧资源,而且我的数据模型(.mom 文件)的旧版本会导致冲突。这就是为什么删除该应用程序可以解决我的其中一台设备上的问题。

After finding this blog postvia another SO answer I made my app more tolerant of old models by changing this line which looks for ALL .mom files:

通过另一个 SO 答案找到这篇博文后,我通过更改查找所有 .mom 文件的这一行,使我的应用程序更能容忍旧模型:

NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];

to this, which only looks in the Filters directory:

对此,仅在 Filters 目录中查找:

NSString *path = [[NSBundle mainBundle] pathForResource:@"Filters" ofType:@"momd"];
NSURL *momURL = [NSURL fileURLWithPath:path];
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];

I used recursivePathsForResourcesOfTypefrom this so question: to help figure this out by logging all of the .mom files in the app:

我从这个问题中使用了recursivePathsForResourcesOfType:通过记录应用程序中的所有 .mom 文件来帮助解决这个问题

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

I also used iExplorerto look at the extraneous .mom files (I didn't try deleting them yet).

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

The method below was also helpful. It showed that an entity was in the merged model returned by [psc managedObjectModel] that didn't exist any more in any of my models or in the store itself. This was what let me to believe an old model was being cached on the device itself that clean building didn't remove. The method logs each entity that is the same, been changed, or added to, or removed from the model. (written with this SO answeras a starting point):

下面的方法也很有帮助。它表明一个实体在由 [psc managedObjectModel] 返回的合并模型中,在我的任何模型或商店本身中不再存在。这就是让我相信旧模型缓存在设备本身上的原因,而干净的建筑没有删除。该方法记录每个与模型相同、已更改、添加到模型或从模型中删除的实体。(以这个 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;
}

usage: called before adding each store to NSPersistentStoreCoordinator :

用法:在将每个商店添加到 NSPersistentStoreCoordinator 之前调用:

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

回答by pierrotlefou

Every time you making change to the Core Date definition, you should delete the apps installed on the physical device or simulator.

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

回答by Tom Howard

  1. Stop app from running.
  2. Delete app on simulator.
  3. Product- > Clean
  4. Build, run.
  1. 停止应用程序运行。
  2. 在模拟器上删除应用程序。
  3. Product- > Clean
  4. 构建,运行。

回答by Naishta

The simplest solution that worked for me in Swift 2.1, Xcode 7 is :

在 Swift 2.1,Xcode 7 中对我有用的最简单的解决方案是:

  1. Delete the app from the Simulator ( Cmd + Shift + H to go to the Home Screen. Long Press the app, Click cross, just the usual way you delete an app from your phone)

  2. Cmd + Shift + H again to stop the dancing of apps

  3. Go back to your project and rerun

  1. 从模拟器中删除应用程序( Cmd + Shift + H 转到主屏幕。长按应用程序,单击十字,就像从手机中删除应用程序的常用方法)

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

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

I had this issue while writing/reading from Core Data with 2 entities set up. Deleting the app and rerunning the program fixed the issue

我在设置了 2 个实体的情况下从 Core Data 写入/读取时遇到了这个问题。删除应用程序并重新运行程序修复了问题