2011-11-01 58 views
10

我想在我的应用程序中实现CoreData来存储小型数据库。核心数据崩溃:[__NSArrayM insertObject:atIndex:]:object can not be nil

这里我实现的:

AppDelegate.h

#import <UIKit/UIKit.h> 
#import "FavoritosViewController.h" 
#import <CoreData/CoreData.h> 

@interface XXX : NSObject <UIApplicationDelegate>{ 

    NSManagedObjectModel *managedObjectModel; 
    NSManagedObjectContext *managedObjectContext;  
    NSPersistentStoreCoordinator *persistentStoreCoordinator; 



} 
- (NSString *)applicationDocumentsDirectory; 

@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel; 
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext; 
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator; 

@end 

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ 

    FavoritosViewController *global=[[FavoritosViewController alloc]init]; 

    global.managedObjectContext=[self managedObjectContext]; 

    . 
    . 
    . 
    } 

     - (void)applicationWillTerminate:(UIApplication *)application 
    { 
     NSError *error = nil; 
     if (managedObjectContext != nil) { 
      if ([managedObjectContext hasChanges] && ![managedObjectContext save:&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. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button. 
       */ 
       NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
       abort(); 
      } 
     } 

    } 

- (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 by merging all of the models found in the application bundle. 
*/ 
- (NSManagedObjectModel *)managedObjectModel { 

    if (managedObjectModel != nil) { 
     return managedObjectModel; 
    } 
    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];  
    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; 
    } 

    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"FavoritosDatabase.sqlite"]]; 

    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. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button. 

     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. 
     */ 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     abort(); 
    }  

    return persistentStoreCoordinator; 
} 




- (NSString *)applicationDocumentsDirectory { 
    return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; 
} 

我也有xcdatamodeld “事件” 与他们的实体属性,Event.h ,来自它的Event.m。

在FavoritosViewController我也有所有的方法,但问题出现在所有这些之前。

它是在

managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];  

的应用程序崩溃并出现以下内容:

*终止应用程序由于未捕获的异常 'NSInvalidArgumentException',原因是:“* - [__ NSArrayM insertObject:atIndex:]:object can not be nil'

An y的想法?谢谢!!!

回答

28

当我的代码运行[NSManagedObjectModel mergedModelFromBundles:nil]时,我遇到了同样的错误信息。这发生在xCode意外地撞上我之后。即使当我恢复到我的代码的已知良好版本时,我仍然有同样的错误,这是由于某种形式的腐败。

多尝试之后,我能够通过退出Xcode和iPhone的模拟器,然后从以下目录中删除所有文件来解决问题:

$ cd /Users/john/Library/Developer/Xcode/DerivedData 

$ rm -R -f ./(folder corresponding to my project name) 

$ cd /Users/john/Library/Application Support/iPhone Simulator/5.0/Applications 

$ rm -R * 

这是能够清除损坏的临时文件和状态为模拟器,并且错误消失。

+1

你救了我的命。 – Snowman

+0

我不知道OP,但这绝对适合我。谢谢!我一直在寻找这个答案。 – solydest

+0

对我来说也适用,对我而言,这是重命名模型文件后发生的事情。 – PKCLsoft

-1

发生崩溃是因为您编写的代码试图在MutableArray中插入一个零。调试你的应用程序插入对象的位置,并检查对象!= nil然后插入数组,否则NSLog(@“Object is nil”);

+0

你的意思是检查managedObjectModel是否为零?在 - (NSManagedObjectModel *)managedObjectModel;这已经被检查。在这种方法失败。 – saimonx

+0

没有你在可变数组中插入对象的地方。崩溃是由于试图插入一个零对象。我认为你应该使用自我。 managedObjectContext因为你正在使用属性。否则,如果您将managedObjectContext传递给另一个类,则会发生崩溃。 –

+0

这个答案与实际问题无关。几乎所有其他的答案都是在钱上。这不是一个可以通过更改他的代码来解决的问题。这是由于对模型文件做了某些事情而导致的由Xcode引起的环境问题。 – PKCLsoft

-1

“我得到了类似的错误。但不是核心数据。我得到了阵列错误。所以我做了什么插入之前只是检查对象,并添加..”

NSMutableArray *tmpArr = [[NSMutableArray alloc] init]; 
NSString *name; 
name = @"sample"; 
if(name) 
[tmpArr addObject:name]; 
+0

它在我的xcode中工作。 – GameLoading

+0

不幸的是,这个答案没有帮助 - 无效的调用发生在Apple的核心数据框架内;该修补程序不是有一个无效的coredata模型。 – JosephH

2

当初类似的错误。当您第一次在Xcode中创建模型时,似乎在内部存储模型的名称

我重命名了模型文件 - 这导致了OP提到的问题。

恢复模型名称(并进行构建清理+删除应用程序窗体设备)为我解决了这个问题。

+0

我有这个问题,但能够通过选择模式的旧版本来修复它的内部参考,然后重新选择我的新重命名版本。并重置模拟器。 –

0

我刚才有这样的问题。问题出在模型文件中,我有一个版本化的模型文件,不知何故当前模型版本里面没有文件(可能是一些svn提交错误)。 所以我已经添加了缺少的文件,选择它作为当前模型,一切正常。


注意替换模型文件符兼容的设备/软件现有的仓库,即使是相同的(纠正我,如果我错了,但就是那样对我来说)。所以轻量级迁移不会工作,如果您:

  1. 有版本1和2
  2. 运行的应用和使用模式模型2
  3. 2' 代替模型文件版本2(即使有相同的字段/类型)

现有的设备/模拟器存储不会与2' 工作,你会得到2或具有重量轻迁移打破了这些设备/ simuator储存

6

我感动我的Model.x cdatamodeld文件到另一个文件夹,并得到这个错误。从干净的模拟器开始并没有帮助。显然,Xcode在某处保留对该文件的引用。

我的修复是备份我的旧Model.xcdatamodeld文件,将其从项目中删除,在同一个文件夹中创建一个新的模型文件,然后用备份替换此文件。

+0

这为我解决了这个问题,非常感谢! – Macondo2Seattle

1

我在重命名核心数据模型文件后发生了完全相同的错误。删除Xcode/DerivedData目录,清理项目,从模拟器中卸载应用程序,重新启动Xcode,升级Xcode等都不起作用。

为了让它再次运行,我从顶部菜单中选择了“iOS模拟器” - >“重置内容和设置...”。

1

这里有很多答案,但我不确定他们中的任何一个都能够清楚地说出究竟是什么错误。

我的理解是,这种崩溃的根本原因在于,您的应用安装在设备上时,其模型为空。例如。如果您使用iFunBox/iExplore查看设备,则会看到一个MyApp.app/MyModel.momd,它具有VersionInfo.plist,其中NSManagedObjectModel_VersionHashes字典为空,或者NSManagedObjectModel_CurrentVersionName指向不存在的模型。

原因可能会有所不同,但基本上都与您的模型没有在xcode中正确设置有关。在我们的例子中,项目文件与文件系统不同步,并且模型与xcode的位置不同,但是最新版本的空白也会导致它。通过从xcode中移除项目并再次添加项目,然后检查最新版本是否正确设置,可以修复大部分这些问题。

由于这种性质的问题,从一个干净的状态进行测试也很重要 - 也就是说,清理xcode中的构建文件夹(cmd-shift-option k)从设备/模拟器中删除应用程序(否则xcode可能会让文件处于周围,使其看起来像事情正在工作)。

似乎有一个xcode中的错误(至少在xcode 4.6和5.0.1中),这意味着它在某些情况下不会发出构建警告,当它应该能够。我已经在Apple的bugreporter中提出了这个问题,解释为15186008。在这种

0

的问题可能要解决:

  • 删除应用程序在模拟器
  • 请使用cmd + alt + shift + k

然后重新生成并运行一次深层清洁你的应用。

帮助我总是在CoreData的开发阶段!

0

通过从项目中删除* .xcdatamodeld引用并重新添加它来解决该错误。

相关问题