没有完全解决这个问题的现有技术: 核心数据迁移错误消息“'模型不包含配置'XYZ'。'”
我已将其缩小到一个特定问题。不过,设置需要一分钟。请多多包涵。
问题的要点是persistentStoreCoordinator(显然)不能保留对象图的一部分,其中当托管对象存储在不同文件中时,它们被标记为另一个对象的子实体。开始...
1) 我有 2 个 xcdatamodel 文件,每个文件都包含一个实体。在运行时,当构建托管对象模型时,我使用 setSubentities: 手动将一个实体定义为另一个实体的子实体。这是因为尚不支持在编辑器中跨多个文件定义子实体。然后我用 modelByMergingModels 返回完整的模型。
//Works!
[mainEntity setSubentities:canvasEntities];
NSLog(@"confirm %@ is super for %@", [[[canvasEntities lastObject] superentity] name], [[canvasEntities lastObject] name]);
//Output: "confirm Note is super for Browser"
2) 我修改了 persistentStoreCoordinator 方法,以便为每个实体设置不同的存储。从技术上讲,它使用配置,并且每个实体都定义了一个且只有一个配置。
//Also works!
for ( NSString *configName in [[HACanvasPluginManager shared].registeredCanvasTypes valueForKey:@"viewControllerClassName"] ) {
storeUrl = [NSURL fileURLWithPath:[[self applicationDocumentsDirectory] stringByAppendingPathComponent:[configName stringByAppendingPathExtension:@"sqlite"]]];
//NSLog(@"entities for configuration '%@': %@", configName, [[[self managedObjectModel] entitiesForConfiguration:configName] valueForKey:@"name"]);
//Output: "entities for configuration 'HATextCanvasController': (Note)"
//Output: "entities for configuration 'HAWebCanvasController': (Browser)"
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:configName URL:storeUrl options:options error:&error])
//etc
3)我为父实体设置了一个 fetchRequest,其中 setIncludesSubentities: 和 setAffectedStores: 只是为了确保我们同时涵盖了 1) 和 2)。当插入任一实体的对象时,它们都被添加到上下文中,并且它们都由 fetchedResultsController 获取并按预期显示在 tableView 中。
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entity];
[fetchRequest setIncludesSubentities:YES]; //NECESSARY to fetch all canvas types
[fetchRequest setSortDescriptors:sortDescriptors];
[fetchRequest setFetchBatchSize:20]; // Set the batch size to a suitable number.
[fetchRequest setAffectedStores:[[managedObjectContext persistentStoreCoordinator] persistentStores]];
[fetchRequest setReturnsObjectsAsFaults:NO];
这是它开始行为不端的地方:关闭并重新启动应用程序后,仅获取父实体。
如果我使用 setEntity: 将请求的实体更改为“Note”的实体,则会获取所有注释。如果我将其更改为“浏览器”的实体,则会获取所有浏览器。让我重申一下,在对象首次插入上下文的运行期间,它将出现在列表中。只有在保存并重新启动后,获取请求才无法遍历层次结构。
因此,我只能得出结论,问题在于继承的存储。让我们回顾一下原因:
- - 两个实体都可以创建、插入到上下文中并查看,因此模型正在工作
- - 两个实体都可以通过一个请求获取,因此继承工作正常
- - 我可以确认文件正在单独存储,并且对象正在进入相应的存储区,因此正在保存
- - 使用为请求设置的任一实体启动应用程序都有效,因此从商店中检索工作正常
- - 这也意味着使用请求遍历不同的商店是有效的
- - 通过使用单个商店而不是多个商店,问题完全消失了,因此创建、存储、获取、查看等工作正常。
这只留下了一个罪魁祸首(在我看来):我使用 setSubentities 设置的继承:仅对会话期间创建的对象有效。
要么对象/实体被存储而没有继承信息,要么以编程方式定义的实体继承仅适用于新实例,或两者兼而有之。其中任何一个都是不可接受的。要么它是一个错误,要么我是方式,方式偏离路线。
我已经在这四处走动了两天;非常感谢任何见解。当前的解决方法 - 仅使用单个商店 - 完全有效,但如果我从应用程序中删除其中一个模型等,它不会是面向未来的。它也令人难以置信,因为我不明白为什么你如果核心定义(setSubentities:)不起作用,则将拥有所有这些基础架构,用于跨多个商店进行存储并在获取请求中设置受影响的商店。