无法使用nil模型创建NSPersistentStoreCoordinator


96

我第一次接触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;
}

嘿,就像将单词“ Model”附加到第一个URLForResource参数一样简单....是的,我遇到了同样的问题。然后,我在命令行中检查了实际的.app内容,发现.momd实际上是在创建的。因此,请尝试以下操作:[[NSBundle mainBundle] URLForResource:@“ RugbyOnTvModel” withExtension:@“ momd”];
PostCodeism 2012年

NSString *basePath = [paths firstObject];
William Entriken 2014年

Answers:


157

我有与原始帖子完全相同的错误消息。我为此努力了几个小时。这是我AppDelegate.m中的这一行。

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

对于在那里搜索此错误消息并找到此线程的任何人。

您必须确保它说的是[与xcdatamodeld的名称相同]...。由于某种原因,我的项目名称在那里,而不是数据模型名称。

更改它,它立即起作用.....

感谢Rock&Muller的贡献....您救了我几天!

加兹


2
这是使它对我有用的评论。我的应用程序正在寻找的神奇名称是blahfrom blah.xcdatamodeld。谢谢互联网,以及stackoverflow。
Acedanger 2013年

我有“ Model.xcdatamodeld”,已更改为“ Model”作为参数。但是Xcode拒绝加载它,但是这个文件确实存在!我不知道,这是怎么回事。
达尔曼·阿曼巴耶夫

哇。谢谢,我一阵子都在打我的头。
Sani Elfishawy 2014年

那storeURL呢?
MoralCode 2014年

54

首先验证:

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

如果您得到一个零值,也许问题就在这里

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

因此,尝试将@“ momd”更改为@“ mom”


1
你的权利。它为空,因此此行引起错误:`__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[selfmanagedObjectModel]];`改成妈妈似乎并不能解决任何问题
Dominic Williams

3
很有可能modelURL也是nil。最常见的原因是输入错误RugbyOnTv。请注意,这是区分大小写的。
罗布·纳皮尔

1
将“ momd”更改为“ mom”也对我有用。谢谢。但为什么?为什么XCode生成不起作用的代码?为什么在SO中找到像这样的晦涩修补程序才能使基本模板正常工作?
大黄

10
最近介绍了我的模型的第二版后,我不得不将其改回momd。鉴于模型版本容器具有xdatamodeld的扩展名,我认为我们可以推断这里发生了什么。“ momd”用于具有多个版本的模型,而“ mom”用于没有版本控制的模型。
杰拉尔德

2
我将代码原样复制到一个新项目[iOS7]中,该项目最初是momd,但是改由mom修复。我不知道没有这个我怎么能找到一个解决方案,所以谢谢:)
Ian Clay13年

20

我在Xcode 4.3.2和iOS 5上遇到了一个奇怪的问题。

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

返回有效的URL,但是

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

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

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

然后工作。尽管Xcode生成的代码本身不起作用,这似乎很奇怪。


1
此特定问题是由于创建额外的模型版本,然后尝试在Xcode打开时手动将其删除而引起的。这会导致某种腐败。您不应在momd目录中传递特定的模型版本。
Mike Weller 2012年

酷@MikeWeller,很高兴知道。您知道指向momd目录中mom文件的元数据在哪里吗?
xster 2012年

我没有试图删除它,但是我遇到了这个问题,发布的解决方案对我有用,特别是,我只是添加了一个检查以查看它是否仍然为零,是否添加了上面的代码:if(_managedObjectContext == nil){NSURL * modelURL = [[NSBundle mainBundle] URLForResource:@“ Model” withExtension:@“ mom”子目录:@“ Model.momd”];_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; }
David van Dugteren 2012年

19

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

PS:仅在我更改了数据模型文件的名称之后,才开始出现此问题。


2
对于每个遇到以下问题的人:重命名xcdatamodeld文件后,managedObjectModel将为nil:最佳答案!感谢JDx,您的回答对我有很大帮助!
Dumoko 2012年

您可以最终编辑它而不是删除它,以便将存储的文件名更改为youl xcdatamodel的最新版本
Furins 2014年

13

该错误的另一个来源是,有时Xcode在构建中不包含数据模型。

检查目标的构建阶段,并确保* .xcdatamodeld文件包含在“编译源”部分中。


这为我解决了。
本·托马斯

这对我有用。当它在Simulator而非实际设备上运行时,它令人沮丧且难以调试!
Bishal Ghimire

9

可能发生的是,来自Apple源代码的xcdatamodeld文件已转换为xcdatamodel(不带d)文件,因此认为它们不相同。

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

Editor->Add Model Version...

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

这适用于Xcode 5


不幸的是,此选项在Xcode 5中不存在。请参阅此处
大约2014年

忘了提到您需要选择xcdatamodel文件。编辑答案以反映评论。
路易·克雷曼

8

我通过将db文件添加到中来解决此问题Copy Bundle Resources

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

在此处输入图片说明

没有发布的解决方案对我有用。因此,希望这篇文章可以帮助某人。我的应用仅在发布版本中崩溃。学过的知识。始终测试发布版本!

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


6

我在@Dominic Williams遇到了同样的问题

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

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

5

我有同样的问题。解决方案是2个答案的组合:

1)我必须将“子目录”参数添加到URLForResource调用中

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

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

仅使用上述解决方案之一,我的应用程序无法正常工作。


4

您提到的问题的解决方案很简单。在模型URL中将文件扩展名更改为“ mom”,而不是“ momd”。做完了


4

我在这里尝试了所有解决方案,但没有一个起作用。重命名项目后出现了我的问题。显然,Xcode在编译过程中会继续在错误的位置查找旧的momd文件。

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


4

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

  1. 在xcode中创建新的Model版本。(选择.xcdatamodeld,打开编辑器菜单,然后单击“添加模型版本...”)
  2. 编译并确保新版本有效。
  3. 将旧版本设置为当前版本。(.xcdatamodeld版本不足的核心数据模型在文件检查器中为“当前” )
  4. 删除对.xcdatamodeldxcode中文件的引用
  5. 右键单击.xcdatamodeldFinder中的文件,然后选择“显示软件包内容”
  6. 删除.xcdatamodel不需要的新
  7. .xcdatamodeld在xcode中重新添加
  8. 编译和微笑

(这是我找到如何删除模型版本的地方:如何在Xcode中删除旧的/未使用的数据模型版本


发牢骚!这非常有帮助。
Michael Dorner 2015年

4

我无需更改任何代码即可解决问题。

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

 NSString *path=@"ModelName";

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

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

1

在我这边的问题是,我更改了数据库名称中几个字符的大小写。

启动新项目时,Xcode会自动从项目名称设置所有内容。如果您开始将项目命名为“ Rugbyontv”,后来又决定更改为“ RugbyOnTV”并进行搜索和替换,则可能会破坏它。(感谢Rob指出名称区分大小写)


1

我一直在寻找答案几个小时,但没有任何效果。但是后来我突然发现了这篇文章。因此,据此,问题出在AppDelegate.m的这一部分中设置了根控制器:

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

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

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

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

并且一切正常。


1

我知道这不能解决您的问题,但是昨天我遇到了困扰我数小时的问题,@ Dominic Williams发布的解决方案给了我ArrayIndexOutOfBoundsException(与Objective-C等效)。

我对Objective-C / Xcode不太满意,但是我正在开发我们公司(主要)在外部开发的iOS应用。不幸的是,他们常常会忘记如何使用键盘,并且会交替使用大写字母或拼写错误的属性,但是他们懒得回去修改它。他们在xcode项目名称中使用了不应使用的大写字母(我们的产品名称未使用大写字母),我不得不回过头来将每次出现的大写字母更改为小写; 其中包括项目名称,核心数据文件,数百个变量等。

无论如何,一旦完成此操作,我就会遇到此错误,没有解决方案可以为我解决。我已确保所有URL名称正确,项目清除,应用程序卸载,电话重启等无济于事。我放弃并关闭了Mac,回到家中度过了一天。令我惊讶的是,我今天早上回来了,一切似乎都正常!

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


1

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


1

我有同样的问题,即

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

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

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

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


1

在删除生成的应用后,我从无处不在遇到了这个问题~/Library/Application Support/iPhone Simulator。不知何故,这导致后续构建在模拟器和设备上失败。很久以来,都没有更改与CoreData有关的任何内容,但随着Cannot create an NSPersistentStoreCoordinator with a nil model。尝试了以上几件事,但没有任何效果。

我可以看到生成的momd文件夹,其中包含mom文件。模拟器中的应用程序可以看到两者,但无法生成sqlite文件。

解决问题的方法是在Xcode的xcdatamodeld文件中向实体添加属性,然后立即将其删除。我希望这将使Xcode重新生成从头开始导致问题的任何方式,并且似乎可以正常工作。仍然不清楚实际出了什么问题,但是我的应用现在又在模拟器和设备中运行。


0

我刚从IOS5升级到IOS6时遇到了类似的问题。原来,型号名称是区分大小写的问题。

不知道这是否对任何人有帮助。



0

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

据我了解,大多数情况是在您更改数据模型文件名时发生的。原因可能是这样的:
。首次运行该应用程序时,它将在应用程序捆绑包中创建一个数据模型文件,例如“ data_model_1”。此创建仅第一次发生。
。当您更新文件名并再次运行该应用程序时,将找不到它,因为仍然有“ data_model_1”文件,但您是在告诉它寻找“ data_model_2”。如何找到它,它还没有创建它,除非您不使用新文件名安装该应用程序,否则它将不会找到它。

因此,如果这是您的应用程序的第一个版本,并且在模拟器或设备上重新安装不会损害您的项目,请继续使用。另外,请查看iOS开发者库中的《核心数据模型版本控制和数据迁移指南》,也许这正是您所需要的。

编辑:如果无法重新安装,请先尝试卸载,然后清理项目,然后关闭所有内容,重新打开项目并进行构建+运行。那应该工作。


0

如果您的项目在模拟器上而不在设备上运行,请尝试在设备上运行发布版本,而不是调试版本。

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

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


0

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


0

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


0

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


0

我面临着同样的错误,当我改名.xcdatamodel从xcode的文件和应用程序的委托改变了重新命名的名称能够满足需求,但我仍然得到了同样的错误。建议的程序都不适合我。

然后,我在其中打开文件夹,Finder并找到一个附加文件.xccurrentversion.xcdatamodel文件。我在TextEdit应用程序中将其打开并进行了更改:

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

我将此与Xcode 6.4,OSX Yosemite 10.10.1一起使用

希望对您有所帮助!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.