Reputation: 516
I am trying to implement CoreData in my application to store a small database.
Here my implementation:
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];
}
I have also a xcdatamodeld with "Event" entity with theirs attributes, and Event.h, Event.m from it.
In FavoritosViewController I have also all the methods, but the problem comes before all that.
It comes at
managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
The app crash and it appears the following:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
Any ideas??? Thanks!!!
Upvotes: 10
Views: 15489
Reputation: 1272
Managed to solve this error just by removing the *.xcdatamodeld reference from the project and adding it back again.
Upvotes: 0
Reputation: 2284
Problems in this kind may be solved by:
cmd
+ alt
+ shift
+ k
Then rebuild and run your app.
Helped me always a lot in dev-phase with CoreData!
Upvotes: 0
Reputation: 37495
There's a lot of answers here, but I'm not sure any of them concisely state exactly what is wrong.
My understanding is that the root cause of this crash is that your app, when installed on the device, has a model that is empty. eg. if you look on the device with iFunBox/iExplore, you see a MyApp.app/MyModel.momd that has a VersionInfo.plist where the NSManagedObjectModel_VersionHashes dictionary is empty, or the NSManagedObjectModel_CurrentVersionName points at a model that doesn't exist.
The reasons for that can vary, but basically all relate back to your model not being setup properly in xcode. In our case the project file had got out of sync with the filesystem and the model was in a different location to where xcode though it was, but having an empty latest version could also cause it. Most of these can be fixed by removing the project from xcode and adding it again, then checking the latest version is correctly set.
With problems of this nature, it's also pretty important to test from a clean state - ie. cleaning the build folder in xcode (cmd-shift-option k) and deleting the app from the device/simulator (as otherwise xcode can leave files lying around that make it look like things are working).
There appears to be a bug in xcode (at least in xcode 4.6 and 5.0.1) that means it doesn't issue a build warning in some of these cases when it should be able to. I've raised that in Apple's bugreporter as 15186008.
Upvotes: 1
Reputation: 269
I had exactly the same error after I renamed the core data model file. Deleting Xcode/DerivedData directory, cleaning project, uninstalling app from simulator, restarting Xcode, upgrading Xcode, etc. did not work.
In order to get it to work again, I have selected "iOS Simulator" -> "Reset Content and Settings..." from the top menu.
Upvotes: 1
Reputation: 4552
I moved my Model.xcdatamodeld file to another folder, and got this error. Starting with a clean emulator didn't help. Apparently Xcode keeps a reference to this file somewhere.
My fix was to backup my old Model.xcdatamodeld file, remove it from the project, create a new model file in the same folder and then replace this file with the backup.
Upvotes: 6
Reputation: 6032
I've had issue like this just now. The problem was in model file, I had a versioned model file and somehow there was no file inside for current model version (probably some svn commit error). So I've added that missing file, selected it as a current model and everything worked fine.
Note that replacing model file breaks compatibility with existing storages on devices/simulators, even if it's the same (correct me if I'm wrong, but that was like that for me). So lightweight migration wont work if you:
existing device/simulator storage won't work with 2', you're going to get 2 or have lightweight migration broken for those device/simuator storages
Upvotes: 0
Reputation: 19870
Had a similar error. When you first create the model in Xcode, it seems to store the name of the model internally.
I renamed the model file - this caused the problem mentioned by OP.
Reverting the model name back (and doing a build clean + deleting the app form the device) fixed the issue for me.
Upvotes: 2
Reputation: 105
"I got similar error.. But not for the Core Data.. I got error for Array.. So What I did is just check the object before inserting and added.."
NSMutableArray *tmpArr = [[NSMutableArray alloc] init];
NSString *name;
name = @"sample";
if(name)
[tmpArr addObject:name];
Upvotes: -1
Reputation: 358
I had a similar problem with the same error message when my code ran [NSManagedObjectModel mergedModelFromBundles:nil]. This happened after xCode crashed on me unexpectedly. Even when I reverted back to a known good version of my code, I still had the same error that was due to some sort of corruption.
After much experimenting, I was able to solve the problem by exiting Xcode and the iPhone simulator, and then deleting all files from the following directories:
$ 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 *
This was able to clear the corrupted temporary files and state for the simulator, and the error disappeared.
Upvotes: 28
Reputation: 28720
The crash occurs because the code you have written is trying to insert a nil in a MutableArray. Debug your app where you are inserting objects and check if object != nil then insert in array otherwise NSLog(@"Object is nil");
Upvotes: -2