迁移Core Data存储时出现错误消息

问题:

我有一些非常简单的代码(如下),在“ migratePersistentStore ”期间会导致出现exception并显示错误消息

 Exception:*** -[__NSArrayM replaceObjectAtIndex:withObject:]: object cannot be nil 

代码:

 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); } } 

更多信息:

  • 看来,如果没有数据存在,则不会发生exception。 而相同的函数设置一个错误,与userInfo“ 不能添加两次相同的存储 ”。
  • 我正在做一个简单的小项目来尝试复制这个问题,一旦完成,我会在这里发布一个链接。

显然,当您的iCloud URL和本地URL相同时,Core Data不喜欢迁移。 我认为这应该不重要,因为真的,iCloud的数据存储在自己的目录。 但是,在迁移期间,似乎使用相同的名称会导致问题。

轻松修复 – 只需要做这样的事情:

 - (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"]; } } 

这里真的没有足够的信息来告诉你确切的原因。 正如你可能已经猜到的,CoreData正在运行一个问题,它将用一个零对象replace一个数组中的一个对象。 如果您的映射模型不匹配,就会发生这种情况。

要解决您的问题,您应该做两件事:

  1. 除去try / catch,而是为所有exception设置一个符号断点。 这会导致debugging器在遇到此exception时停止,并且您可以看到堆栈跟踪以及应用程序中发生的其他事情。 请注意,如果CoreData运行到合并冲突,这些在CoreData内部作为exception处理,debugging器也将停止。 在这种情况下,直到数组exception。

  2. 设置你的应用程序的启动参数来打开迁移日志logging来看看它到底是如何实现的。 在Xcode中,编辑您的应用程序scheme的运行任务以传递-com.apple.CoreData.MigrationDebug 。 请注意,论点之前的破折号很重要。 CoreData将logging你的迁移过程中发生的情况,这应该有助于查明问题。

你的计划应该是什么样子

随机猜测:你有没有在你的模型中声明NSManagedObject子类,你忘记了在你的构build中包含一个实现? 在这种情况下,迁移代码尝试创build自定义子类的实例是不可能的,然后在将结果投入数组之前无法检查成功。

在没有迁移的情况下运行并执行类似以下操作来检查:

 for(NSEntityDescription *entityDescription in model.entities) { NSString *className = [entityDescription managedObjectClassName]; Class class = NSClassFromString(className); if(className && !class) NSLog(@"An implementation of class %@ is missing from the build", className); }