持久存储的核心数据错误 [英] Core Data Error With Persistent Store

查看:102
本文介绍了持久存储的核心数据错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用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:@CoreDataSQLiteofType: @sqlite]];
NSError * err = nil;

if(![[NSFileManager defaultManager] copyItemAtURL:preloadURL toURL:storeURL error:& err]){
NSLog(@糟糕,可以复制预加载的数据);
}
}

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

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

/用代码来正确处理错误。

abort()导致应用程序生成崩溃日志并终止。您不应在运送应用程序中使用此功能,但在开发过程中可能很有用。

此处的错误的典型原因包括:
*持久存储不可访问;
*持久存储的模式与当前管理对象模型不兼容。
检查错误消息以确定实际问题是什么。


如果永久存储不可访问,则文件路径通常有问题。通常,文件URL指向应用程序的资源目录,而不是可写目录。

如果在开发期间遇到模式不兼容性错误,可以通过以下方式减少它们的频率:
*简单地删除现有存储:
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil ]

*通过传递以下字典作为options参数执行自动轻量级迁移:
[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],NSMigratePersistentStoresAutomaticallyOption,[NSNumber numberWithBool:YES],NSInferMappingModelAutomaticallyOption,零];

轻量级迁移只适用于一组有限的模式更改;有关详细信息,请参阅核心数据模型版本控制和数据迁移编程指南。
* /

NSLog(@未解析的错误%@,%@,错误,[错误userInfo]);
abort();
}

return __persistentStoreCoordinator;
}

正如你所看到的,我从sqlite db预加载数据。一切工作完美。它能够从模型中提取数据并正确显示。





当我将第二个实体添加到同一个模型时,对于应用程序的最后部分。应用程序决定崩溃的abort();说明以下内容:

 用于打开商店的模型与用于创建商店的模型不兼容; 

现在这是一个简单的修复,因为我发现因为谷歌研究。转到应用程序并删除它,然后将重置所有数据库的数据,并让它重新加载。然而,我已经这样做,它仍然继续不工作。以下是我尝试过的所有结果:




  • 删除应用程式

  • 内容和设置。

  • 将storeURL的名称更改为其原始值以外的其他值。

  • 删除列出的商店网址



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



我不知道发生了什么,这是非常令人沮丧,因为我不知道如何解决这个问题。 Google正在用尽这个问题的解决方案,所以我想我会得到奇妙的堆栈溢出 以获得奇迹解决方案来结束这个挫折。谢谢!

解决方案

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



直接从 Core Data doc


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


如果为 NSMigratePersistentStoresAutomaticallyOption 设置 YES 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 / 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]){

}
/ pre>

I am trying to load simple data from a model using Core Data and putting it into a table view. Here is the following code for my persistent store:

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

As you can see I am preloading data from an sqlite db. Everything works perfectly. It was able to pull data from the model and display it correctly.

BUT

Things changed when I added a second entity into the same model for the last part of the application. The app decides to crash on the "abort();" saying the following:

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

Now this is a simple fix as I have found out because of Google research. Go to the app and delete it then that will reset the data of all the databases and let it reload. However I have done that and it still continues to not work. Here is all that I have tried with still the same result:

  • Deleting the app
  • Resetting content and settings on iPhone simulator
  • Changing the name of the storeURL to something different other than its original value.
  • Removing the store URL as listed in the comments of the code above
  • Cleaning the project

I have come to the conclusion that it is because I have added another entity because when I delete the entity it runs perfectly and goes back to normal without any problems.

I have no idea what is going on which is very frustrating because I do not know how to fix this. Google is running out of solutions to this problem so I thought I would get on the wondrous Stack Overflow to get a miracle solution to end this frustration. Thanks!

解决方案

The motivation is quite simple. When you modify the model, Core Data does not know how to map it.

Directly from Core Data doc

Changing a model will therefore make it incompatible with (and so unable to open) the stores it previously created. If you change your model, you therefore need to change the data in existing stores to new version—changing the store format is known as migration.

If you set YES for NSMigratePersistentStoresAutomaticallyOption and for NSInferMappingModelAutomaticallyOption you should be ok. This is also called LightWeight migration.

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

Edit

Simply pass options dictionary to addPersistentStoreWithType:configuration:URL:options:error as created in the following snippet.

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]) {

}

这篇关于持久存储的核心数据错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆