问题:
我有一些非常简单的代码(如下所示),在migratePersistentStore
' 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);
}
}
守则:
{{1}}
更多信息:
答案 0 :(得分:7)
显然,当您的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"];
}
}
答案 1 :(得分:5)
这里确实没有足够的信息告诉你确切的原因。正如您可能已经猜到的那样,CoreData正遇到一个问题,即它使用nil对象替换数组中的对象。如果映射模型不正确匹配,就会发生这种情况。
要解决您的问题,您应该做两件事:
删除try / catch,而不是为所有异常设置符号断点。这将导致调试器在遇到此异常时停止,您可以看到堆栈跟踪以及应用程序中正在发生的所有其他操作。请注意,如果CoreData遇到合并冲突,这些会在CoreData内部作为异常处理,调试器也将停止在这些异常上。在这种情况下,只需继续,直到您的数组异常。
设置应用程序的启动参数以打开迁移日志记录,以了解它是如何实现此目的的。在Xcode中,编辑应用程序方案的运行任务以传递-com.apple.CoreData.MigrationDebug
。请注意,参数前面的破折号很重要。 CoreData将记录迁移过程中发生的情况,这有助于查明问题。
答案 2 :(得分:2)
随机猜测:您是否在模型中声明了任何NSManagedObject
子类,而您忘记在构建中包含实现?在这种情况下,可以想象迁移代码可能会尝试创建自定义子类的实例,但是没有这样做,然后在将结果抛出到数组之前无法检查它是否成功。
在没有迁移的情况下运行并执行以下操作以检查:
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);
}