The Problem:
I've got some pretty simple code (below) that causes an exception during 'migratePersistentStore
' with the error message
Exception:*** -[__NSArrayM replaceObjectAtIndex:withObject:]: object cannot be nil
The Code:
NSPersistentStore * oldStore = [_persistentStoreCoordinator persistentStores][0];
if (oldStore) {
@try {
[_persistentStoreCoordinator migratePersistentStore:oldStore
toURL:[self storeURL]
options: @{ NSPersistentStoreRemoveUbiquitousMetadataOption : @YES }
withType:NSSQLiteStoreType error:&error];
}
@catch(NSException* ex) {
NSLog(@"Exception:%@", ex.description);
}
}
Further Info:
Apparently, Core Data doesn't like migration when your iCloud URL and local URL are the same. I thought this shouldn't matter because really, iCloud data is stored in its own directory. BUT, it seems during migration, using the same name causes problems.
Easy fix - just do something like this:
- (NSURL *)storeURL {
NSURL * documentsDirectory = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:NULL];
if (iCloudEnabled]) {
return [documentsDirectory URLByAppendingPathComponent:@"iCloudEventData.sqlite"];
} else {
return [documentsDirectory URLByAppendingPathComponent:@"EventData.sqlite"];
}
}
There really isn't enough information here to tell you the exact cause. As you may have guessed, CoreData is running into a problem where it is replacing an object in an array with a nil object. This can happen if your mapping models do not match correctly.
To troubleshoot your problem, you should do two things:
Remove that try/catch an instead set a symbolic breakpoint for all exceptions. This will cause the debugger to stop when it hits this exception, and you can see the stack trace and everything else that is going on in your application. Note that if CoreData runs into merge conflicts these are handled inside CoreData as exceptions and the debugger will stop on those as well. In that case, just continue until your array exception.
Set your application's launch arguments to turn on migration logging to see how it's getting to this point. In Xcode, edit your application scheme's Run task to pass -com.apple.CoreData.MigrationDebug
. Note that the dash preceding the argument is important. CoreData will log what happens during your migration, which should help pinpoint the problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With