核心数据崩溃:[__ NSArrayM insertObject:atIndex:]:对象不能为零

时间:2011-11-01 12:06:22

标签: iphone objective-c ios core-data

我正在尝试在我的应用程序中实现CoreData来存储一个小型数据库。

这是我的实施:

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,其中包含带有theirs属性的“Event”实体,以及来自它的Event.h,Event.m。

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

来自

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

应用程序崩溃,显示如下:

  

*由于未捕获的异常'NSInvalidArgumentException'而终止应用,原因:'* - [__ NSArrayM   insertObject:atIndex:]:object不能为nil'

任何想法???感谢!!!

10 个答案:

答案 0 :(得分: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 :(得分:6)

我将Model.xcdatamodeld文件移动到另一个文件夹,并收到此错误。从干净的模拟器开始没有帮助。显然,Xcode会在某个地方保留对此文件的引用。

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

答案 2 :(得分:2)

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

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

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

答案 3 :(得分:1)

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

为了让它再次发挥作用,我选择了“iOS模拟器” - &gt; “从顶部菜单中重置内容和设置...”。

答案 4 :(得分:1)

这里有很多答案,但我不确定是否有任何简明扼要地陈述错误的内容。

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

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

对于这种性质的问题,从干净的状态进行测试也是非常重要的 - 即。清理xcode中的构建文件夹(cmd-shift-option k)从设备/模拟器中删除应用程序(否则xcode会留下文件,使其看起来像是工作正常)。< / p>

xcode中似乎存在一个错误(至少在xcode 4.6和5.0.1中),这意味着它应该能够在某些情况下不会发出构建警告。我在Apple的bug报告器中将其提升为15186008。

答案 5 :(得分:0)

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


请注意,替换模型文件会破坏设备/模拟器上现有存储的兼容性,即使它是相同的(如果我错了,请纠正我,但对我来说就是这样)。如果您这样轻量级迁移不会起作用:

  1. 拥有版本1和2的模型
  2. 运行应用程序并使用模型2
  3. 将版本2的模型文件替换为2'(即使具有相同的字段/类型)
  4. 现有的设备/模拟器存储将无法与2'一起使用,您将获得2或者为这些设备/模拟器存储器打破轻量级迁移

答案 6 :(得分:0)

此类问题可通过以下方式解决:

  • 在模拟器中删除应用
  • 使用cmd + alt + shift + k
  • 进行深层清洁

然后重建并运行您的应用。

在使用CoreData的开发阶段帮助我总是很多!

答案 7 :(得分:0)

通过从项目中删除* .xcdatamodeld引用并再次添加它来管理解决此错误。

答案 8 :(得分:-1)

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

答案 9 :(得分:-1)

“我有类似的错误..但不是核心数据..我得到了数组的错误..所以我做的只是在插入之前检查对象并添加..”

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