【问题标题】:Core Data Error With Persistent Store持久存储的核心数据错误
【发布时间】:2012-12-20 09:39:57
【问题描述】:

我正在尝试使用 Core Data 从模型中加载简单数据并将其放入表格视图中。这是我的持久存储的以下代码:

//AppDelegate.m

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
 {
    if (__persistentStoreCoordinator != nil)
 {
    return __persistentStoreCoordinator;
}

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"vofasmmmnmgd.sqlite"];

if (![[NSFileManager defaultManager] fileExistsAtPath:[storeURL path]]) {
    NSURL *preloadURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"CoreDataSQLite" ofType:@"sqlite"]];
    NSError* err = nil;

    if (![[NSFileManager defaultManager] copyItemAtURL:preloadURL toURL:storeURL error:&err]) {
        NSLog(@"Oops, could copy preloaded data");
    }
}

NSError *error = nil;
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
{

    /* Replace this implementation 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.

     Typical reasons for an error here include:
     * The persistent store is not accessible;
     * The schema for the persistent store is incompatible with current managed object model.
     Check the error message to determine what the actual problem was.


     If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory.

     If you encounter schema incompatibility errors during development, you can reduce their frequency by:
     * Simply deleting the existing store:
     [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil]

     * Performing automatic lightweight migration by passing the following dictionary as the options parameter:
     [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

     Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details.
     */

    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
 }

  return __persistentStoreCoordinator;
}

如您所见,我正在从 sqlite 数据库预加载数据。一切都很完美。它能够从模型中提取数据并正确显示。

但是

当我为应用程序的最后一部分将第二个实体添加到同一模型中时,情况发生了变化。应用程序决定在“abort();”上崩溃说如下:

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

现在这是一个简单的解决方法,因为我通过 Google 研究发现了这一点。转到应用程序并将其删除,然后将重置所有数据库的数据并让它重新加载。但是我已经这样做了,它仍然无法正常工作。这是我尝试过的所有方法,结果仍然相同:

  • 删除应用程序
  • 在 iPhone 模拟器上重置内容和设置
  • 将 storeURL 的名称更改为不同于其原始值的名称。
  • 删除上面代码的 cmets 中列出的商店 URL
  • 清理项目

我得出的结论是,这是因为我添加了另一个实体,因为当我删除该实体时,它运行完美并恢复正常而没有任何问题。

我不知道发生了什么,这非常令人沮丧,因为我不知道如何解决这个问题。谷歌已经没有解决这个问题的办法了,所以我想我会去奇妙的 Stack Overflow 找到一个奇迹般的解决方案来结束这种挫败感。谢谢!

【问题讨论】:

  • @MartinR 听起来很简单,但我在哪里添加注释掉的代码?我是否包含 [[NSFileManager...]] 以及轻量级迁移的代码?
  • 我删除了我的评论,因为 flexaddicted 已经在他的回答中解决了这个问题。
  • 这看起来像 RHManagedObject。如果是,请参考它,因为它不是您的代码

标签: objective-c ios xcode core-data


【解决方案1】:

动机很简单。当您修改模型时,Core Data 不知道如何映射它。

直接来自Core Data doc

因此,更改模型将使其不兼容(因此 无法打开)它之前创建的商店。如果你改变你的 模型,因此您需要将现有商店中的数据更改为新的 版本——更改存储格式称为迁移。

如果您将YES 设置为NSMigratePersistentStoresAutomaticallyOption 和NSInferMappingModelAutomaticallyOption,则应该没问题。这也称为LightWeight 迁移。

NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setValue:[NSNumber numberWithBool:YES]
            forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setValue:[NSNumber numberWithBool:YES]
           forKey:NSInferMappingModelAutomaticallyOption];
NSPersistentStore *store = nil;
store = [coordinator addPersistentStoreWithType:NSSQLiteStoreType
                                        configuration:nil
                                                  URL:storeURL
                                              options:options
                                                error:&error];

编辑

只需将options 字典传递给addPersistentStoreWithType:configuration:URL:options:error,如下面的sn-p 中创建的那样。

NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setValue:[NSNumber numberWithBool:YES]
           forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setValue:[NSNumber numberWithBool:YES]
           forKey:NSInferMappingModelAutomaticallyOption];
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {

}

【讨论】:

  • 非常感谢。但是我是否将其添加到 if (![__persistentStoreCoordinator addPersistentStore...]) 中?
  • @flextaddicted 是的,完美。我在我的项目中添加了轻量级迁移,效果很好。感谢一百万
猜你喜欢
  • 2013-07-11
  • 1970-01-01
  • 2012-06-13
  • 2011-08-11
  • 2015-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-22
相关资源
最近更新 更多