无法使用nil模型创建NSPersistentStoreCoordinator

时间:2011-09-09 11:49:20

标签: objective-c ios core-data

我在Core Data上遇到了第一次破解,我在设备上运行代码时出现以下错误,但在模拟器上运行正常..

  

* 由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'无法使用nil模型创建NSPersistentStoreCoordinator'

我的一些可能导致问题的方法:

    - (NSManagedObjectContext *)managedObjectContext
{
    if (__managedObjectContext != nil)
    {
        return __managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil)
    {
        __managedObjectContext = [[NSManagedObjectContext alloc] init];
        [__managedObjectContext setPersistentStoreCoordinator:coordinator];
    }
    return __managedObjectContext;
}

/**
 Returns the managed object model for the application.
 If the model doesn't already exist, it is created from the application's model.
 */
- (NSManagedObjectModel *)managedObjectModel
{
    if (__managedObjectModel != nil)
    {
        return __managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"RugbyOnTv" withExtension:@"momd"];
    __managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];    
    return __managedObjectModel;
}

/**
 Returns the persistent store coordinator for the application.
 If the coordinator doesn't already exist, it is created and the application's store added to it.
 */
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (__persistentStoreCoordinator != nil)
    {
        return __persistentStoreCoordinator;
    }

    NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"RugbyOnTV.sqlite"];

    NSURL *storeUrl = [NSURL fileURLWithPath:storePath];

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];    
    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];

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

    return __persistentStoreCoordinator;
}


    - (NSString *)applicationDocumentsDirectory {

        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
        return basePath;
    }

修改

我从Apple的CoreDataBooks复制并粘贴了managedObjectContext方法(下面),现在它正常工作......虽然不知道为什么

- (NSManagedObjectModel *)managedObjectModel {
    if (managedObjectModel != nil) {
        return managedObjectModel;
    }
    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];    
    return managedObjectModel;
}

26 个答案:

答案 0 :(得分:157)

我与原帖有完全相同的错误消息。几个小时我一直在摔跤。 这是AppDelegate.m中的这一行。

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"[same with name of xcdatamodeld]" withExtension:@"momd"];

对于那里搜索此错误消息并找到此帖子的人....首先尝试。

你必须确保它所在的位置[与xcdatamodeld的名称相同] ....它是!!! 出于某种原因,我的项目名称在那里,而不是数据模型名称。

改变了它,它立即起作用.....

感谢Rock&穆勒为贡献.......你救了我几天!!

燃气。

答案 1 :(得分:54)

首先验证:

NSLog(@"%@", [self managedObjectModel]);

如果你得到一个零值可能问题就在这里

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"RugbyOnTv" withExtension:@"momd"];

所以,尝试用@“妈妈”改变@“momd”

答案 2 :(得分:20)

我遇到过Xcode 4.3.2和iOS 5的奇怪问题。

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"NAME_OF_THE_MODEL" withExtension:@"momd"];

返回有效的网址,但

__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

返回null NSManagedObjectModel。但是在检查documentation之后,似乎NSManagedObjectModel需要一个文件,其中NAME_OF_THE_MODEL.momd是一个包含NAME_OF_THE_MODEL.mom文件的目录。将URL更改为

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"NAME_OF_THE_MODEL" withExtension:@"mom" subdirectory:@"NAME_OF_THE_MODEL.momd"];

然后工作。虽然Xcode生成的代码不能自行运行,但看起来很奇怪......

答案 3 :(得分:19)

我有这个问题,将“妈妈”改为“妈妈”并没有做任何事情。要修复它,我必须右键单击xcdatamodelId文件>显示包内容然后删除隐藏的.xcurrentversion文件。

P.S:这个问题才在我更改了数据模型文件的名称后才开始发生。

答案 4 :(得分:13)

此错误的另一个原因是,有时Xcode不包含构建中的数据模型。

检查目标的构建阶段,并确保* .xcdatamodeld文件包含在Compile Sources部分中。

答案 5 :(得分:9)

可能发生的事情是Apple的源代码中的xcdatamodeld文件已变成xcdatamodel(没有d)文件,因此它们不一样。

解决此问题的最快方法是在项目导航器中选择xcdatamodel文件并进入菜单栏

Editor->Add Model Version...

并添加新版本的模型。对新版本进行所有更改。

这适用于Xcode 5

答案 6 :(得分:6)

我和@Dominic Williams有同样的问题

尝试更改下面的momd文件名(默认情况下可以在managedObjectModel方法中找到),与您创建的[file name].xcdatamodeld文件相同:

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"[same with name of xcdatamodeld]" withExtension:@"momd"];

答案 7 :(得分:6)

我通过将db文件添加到Copy Bundle Resources来解决它。

转到项目的根目录>>选择目标>>构建阶段>>复制捆绑资源。确保您的xcdatamodeld文件已添加到此处。

enter image description here

所有发布的解决方案都不适合我。所以,希望这篇文章可以帮助那些人。我的应用程序只在发布版本btw崩溃。学过的知识。始终测试发布版本!

顺便说一句,我发现这个SO帖子最有帮助https://stackoverflow.com/a/6708837/951349

答案 8 :(得分:5)

我遇到了同样的问题。解决方案是两个答案的混合:

1)我必须将“subdirectory”参数添加到URLForResource调用

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"DATAMODEL_NAME" withExtension:@"mom" subdirectory:@"DATAMODEL_NAME.momd"];

2)由于我不知道的原因,在编译项目时不包括数据模型。我不得不手动将其添加到“构建阶段/编译资源”中。

只有上述解决方案之一,我的应用程序无效。

答案 9 :(得分:4)

您所说问题的解决方案很简单。将文件扩展名更改为" mom"而不是"妈妈"在模型URL中。完成。

答案 10 :(得分:4)

我在这里尝试了所有的解决方案,但没有一个能够奏效。我重新命名该项目后出现了我的问题。显然,Xcode继续在编译期间在错误的位置查找旧的momd文件。

对于尝试上述所有解决方案但未成功的任何人,请尝试检查.xcdatamodeld文件的完整路径。这对我有用。

答案 11 :(得分:4)

我在不更改任何代码的情况下解决了问题。

我通过File-> Add File添加ModelName.xcdatamodeld,而不是将文件拖到Xcode中。

 NSString *path=@"ModelName";

NSURL *modelURL = [NSURL fileURLWithPath:[path stringByAppendingPathExtension:@"momd"]];

model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

答案 12 :(得分:4)

我有同样的问题,它在iOS6上工作正常,但在iOS5上没有。 这就是我解决它的方法:

  1. 在xcode中创建一个新的Model版本。 (选择.xcdatamodeld,打开编辑器菜单,然后单击“添加模型版本...”)
  2. 编译并确保新版本有效。
  3. 将旧版本设为当前版本。 (版本核心数据模型下.xcdatamodeld的文件检查器中的“当前”)
  4. 删除对xcode
  5. .xcdatamodeld文件的引用
  6. 右键单击Finder中的.xcdatamodeld文件,然后选择“显示包内容”
  7. 删除您不想要的新.xcdatamodel
  8. 在xcode中重新添加.xcdatamodeld
  9. 编译并微笑
  10. (这是我找到如何删除模型版本的地方:How to delete an old/unused Data Model Version in Xcode

答案 13 :(得分:1)

如果有人因同样的问题而被卡住了。确保已正确链接数据库(因为您可能直接从某个示例复制了代码)。
只需在AppDelegate中的 managedObjectModel persistentStoreCoordinator 方法中更新数据库的名称。

答案 14 :(得分:1)

我有同样的问题,即

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyModel" withExtension:@"momd"];

返回nil,因为没有生成.momd文件。

原因是在app目录(例如MyGreatApp / MyGreatApp.app)中,xcode复制了MyModel.xcdatamodeld,而不是从MyModel.xcdatamodeld文件生成MyModel.momd(使用momc)。

解决方案是删除XCode项目浏览器中对MyModel.xcdatamodeld的引用,并将其从finder中拖回到项目中。之后,xcode意识到需要将其编译为.momd。

答案 15 :(得分:1)

我在~/Library/Application Support/iPhone Simulator删除了生成的应用后突然出现了这个问题。不知怎的,这导致后续版本在模拟器和设备上失败。多年来没有改变与CoreData有关的任何事情,但它会因Cannot create an NSPersistentStoreCoordinator with a nil model而失败。试过上面的一些事情,没有任何效果。

我可以看到生成的momd文件夹里面有妈妈文件。模拟器中的应用程序可以看到两者,但无法生成sqlite文件。

解决这个问题的方法是在Xcode的xcdatamodeld文件中为实体添加一个属性,然后立即删除它。我希望这会让Xcode从头开始重新生成任何导致问题的东西,它似乎有效。仍然不清楚实际上是什么问题,但我的应用程序现在又在模拟器和设备中运行。

答案 16 :(得分:1)

我知道这并没有解决你的问题,但我昨天遇到了困扰我几个小时的问题,@Dominic Williams发布的解决方案给了我一个ArrayIndexOutOfBoundsException(无论Objective-C等价物是什么)。

我对Objective-C / Xcode不是很了解,但我正在开发一个我们公司(主要)在外部开发的iOS应用程序。不幸的是,他们经常会忘记如何使用键盘,并且可以互换使用大写字母或拼错属性,但是懒得回去改变它。他们在xcode项目名称中使用了一个大写字母,它不应该是(我们的产品名称不使用资本)而且我必须返回并将这个大写字母的每个出现都改为小写;其中包括项目名称,核心数据文件,数百个变量等。

无论如何,一旦我完成了这个,我遇到了这个错误,没有任何解决方案正在为我修复它。我已确保所有URL名称都正确,项目清理,应用程序已卸载,手机重新启动等,但无济于事。我放弃了,关闭了我的Mac ,回家过了一天。令我惊讶的是,我今天早上回来了,一切似乎都很好!

我不知道为什么会这样,但如果卡住了,请尝试重新启动Mac。

答案 17 :(得分:1)

我几个小时都在寻找答案,没有任何效果。但后来我突然发现了article。所以根据这个,问题是在AppDelegate.m的这一部分设置根控制器:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    ListViewController *rootView = (ListViewController *)self.window.rootViewController;
    rootView.managedObjectContext = self.managedObjectContext;
    return YES;
}

实际上,您应该定义根控制器将委派您的CoreData连接。在我的情况下,我有一个TabBarController连接到其他视图,所以我的targed视图根控制器被定义为TabBar,它导致错误。我改变了

ListViewController *rootView = (ListViewController *)self.window.rootViewController;

ListViewController *rootView = (ListViewController *)self.window.superview;

一切正常。

答案 18 :(得分:1)

就我而言,问题在于我改变了数据库名称中几个字符的大小写。

启动新项目时,Xcode会自动从项目名称中设置所有内容。如果你开始调用你的项目“Rugbyontv”,后来决定改为“RugbyOnTV”并进行搜索和替换,那就会破坏它。 (感谢Rob指出该名称区分大小写)

答案 19 :(得分:0)

对我来说问题是由于我将我的模型从沙箱项目粘贴到我的实际项目。始终确保在项目中使用模型生成模型。

答案 20 :(得分:0)

当我从xcode重命名 .xcdatamodel文件时,我遇到了同样的错误,并在app delegate中更改了重命名的名称,但我仍然遇到了同样的错误。建议的程序都不适合我。

然后我在Finder中打开了该文件夹,找到了另一个文件.xccurrentversion以及.xcdatamodel文件。我在TextEdit应用中打开了它并更改了此内容:

<dict>
    <key>_XCCurrentVersionName</key>
    <string>Your_Renamed_Model_FileName.xcdatamodel</string>
</dict>

我在Xcode 6.4,OSX Yosemite 10.10.1

中使用它

我希望它有所帮助!

答案 21 :(得分:0)

修复命名问题后,错误仍然存​​在。然后它在重新启动Xcode 5后工作。这可能会自动执行与此处提供的一些手动链接建议相同的事情。

答案 22 :(得分:0)

我也遇到了这个问题但是当我更改ModelName.xcdatamodeld文件时它正在运行。所以我认为ModelName.xcdatamodeld文件没有正确添加,所以一旦检查并清理应用程序并运行它。

答案 23 :(得分:0)

如果您的项目在模拟器上工作但在设备上没有,请尝试在您的设备上运行release-build而不是debug-build。

选择您的项目 - &gt;产品 - &gt;编辑方案 - &gt;构建配置[DEBUG - &gt; RELEASE]

现在再次运行该项目,它将起作用。

答案 24 :(得分:0)

好的,我先说一个半解决方案,如果你重新安装应用程序(在模拟器或调试器设备中)它会工作。但这肯定不是真正的解决方案。例如,如果您要更新应用程序,请不要这样做,否则您的新版本可能会崩溃,因为用户不会重新安装它,他们会使用更新按钮。

据我所知,这个问题主要发生在您更改数据模型文件名时。原因可能是这样的:
。当您第一次运行应用程序时,它正在应用程序包中创建数据模型文件,如“data_model_1”。这种创造只是第一次发生 。当您更新文件名并再次运行应用程序时,它将无法找到,因为仍然存在“data_model_1”文件但您要告诉它查找“data_model_2”。它怎么能找到,它还没有创建它,除非你不用新的文件名安装应用程序。

因此,如果这是您的应用的第一个版本并且在模拟器或设备上重新安装不会损害您的项目,请选择它。否则,请检查iOS Developer Library上的Core Data Model Versioning and Data Migration Guide,也许这就是您所需要的。

编辑:如果重新安装不起作用,请先尝试卸载,然后再清除项目,然后关闭所有内容,重新打开项目并构建+运行。这应该有用。

答案 25 :(得分:0)

另见此主题:Unit Test can't find Core Data model file

它帮助我解决了问题 - 只发生在单元测试