核心数据 - 多核数据模型之间的关系

时间:2017-07-06 21:14:44

标签: ios objective-c iphone swift core-data

平台

iOS 10,Xcode 8.3.3

背景

我已经构建了一个利用Core Data的Notes应用程序,我想在我的下一个应用程序中使用这个应用程序,它也将使用Core Data。为简单起见,我们可以调用我的下一个应用程序“ListApp”和我的笔记应用程序“NotesApp”。此ListApp具有列表项,每个列表项可以包含一个或多个注释。

这是我到目前为止所做的:

  1. 从NotesApp中删除了所有不必要的文件,并编译了“NotesApp Framework”。
  2. 将NotesApp Framework链接到ListApp。
  3. 为ListApp设计核心数据模型。具体来说,我创建了一个名为“ListItem”的实体和一个名为“Note”的实体。 ListItem与Note具有多对多关系(一个列表项可以有多个注释)。 Note实体包含一个“noteID”字段,用于引用NotesApp模型中的注释,当然还有反向关系。
  4. 问题

    我需要在ListApp模型中的实体和NotesApp模型中的实体之间形成“关系”。

    我已经研究过配置,而且似乎更多的是将同一模型中的对象存储到不同的持久存储中,除非我缺少某些东西。所以,这没有用。

    然后,我发现获取的属性可用于在多个商店之间形成弱关系。所以,这也无济于事。

    接下来,我在文档中发现有一个名为NSManagedObjectModel.mergedModel的方法(来自:),所以我假设这是可能的。或许这只是为了迁移?

    这就是我被困住的地方。

    原因

    我宁愿不将NotesApp模型中的所有内容重新设计到ListApp模型中。我更喜欢把一切都分开。

    问题

    有没有办法在不同模型中的两个实体之间形成关系?我应该只在ListItem实体类中添加一个函数来手动获取NotesApp模型中的注释吗?我甚至走在正确的道路上还是有更好的选择?

    注意: 我所说的“关系”是能够调用ListItem实体中的属性来获取笔记并以某种方式“关联”特定ListItem的特定注释。

    P.S。如果您知道任何陷阱,有任何一般性建议或知道任何阅读材料,请随时告诉我。

    另外,我一直在研究这个话题几个小时,我似乎无法找到任何相关内容。我假设这是因为它不可能,这是一种可怕的做法,或者我没有使用正确的关键词。

    如果有人需要更多信息,请随时告诉我们!

2 个答案:

答案 0 :(得分:1)

我认为你说你的包有一个包含List实体的模型,另一个包含Note实体。您可以按照建议合并和调整托管对象模型,并使用代码中生成的托管对象模型。

  • 如果您在代码中创建Core Data堆栈(也就是说,您没有使用新的NSPersistentContainer),则可以轻松地在自定义托管对象模型中进行拼接。
  • 如果您正在使用NSPersistentContainer,则必须将其子类化并覆盖managedObjectModel()。我找不到任何文件说你不能那样做,但我不打赌。
  • 如果您是基于文档的,则覆盖UIDocument的managedObjectModel应该可以正常工作。

要创建自定义托管对象模型,请使用NSManagedObjectModel.mergedModel(from :)合并模型。然后,获取Note和List实体decriptions,获取每个属性,mutate,添加新关系,然后将它们设置回模型。你只会在第一次运行时这样做;将自定义托管模型缓存到ivar以便后续运行。

Hmmmm。我刚刚描述的内容,基本上是撕开,调整和重新组合管理对象模型,将是相当多的代码行。如果这只是一个简单的“笔记和列表”应用程序,如果这些只是这两个实体,那么放弃那些.mom文件并从头开始在代码中创建整个托管对象模型的代码可能会少一些。这并不难。戴上Objective-C眼镜,查看script can be redirected中的(function(window, document, undefined) { document.addEventListener('keyup', showDivs, false); })(window, window.document); function showDivs(event) { event = event || window.event; var divsToShow = document.getElementsByClassName("Display-Div"); for (var i = 0; i < divsToShow.length; i++) { if (!divsToShow[i].classList.contains("Block")) { divsToShow[i].classList.add("Block"); break; } } }功能。

答案 1 :(得分:0)

好吧,事实证明我对Core Data Stack略有误解,但这是一项非常简单的任务。基于一些研究和@Jerry Krinock的答案,我能够非常轻松地使用它。

  1. 创建一个包含NotesApp所需文件的框架。
  2. 将框架链接到ListApp。
  3. 获取对ListApp和NotesApp NSManagedObjectModel可变引用。
  4. 以编程方式在ListApp模型中的ListItem实体和NotesApp模型中的Note实体之间添加NSRelationshipDescription(反之亦然)。
  5. 通过合并ListApp和NotesApp模型创建NSManagedObjectModel
  6. 注意:正如@Jerry Krinock所说,这只需要完成一次,因为我们将两个模型合并在一起并将它们存储在同一个持久存储中。这与通过CoreData Model Builder UI进行编程相同,因为它不支持从单独模型引用实体(至少不是我知道或可以找到的实体)。

    <强>参考文献:

    Core Data Programming Guide

    Core Data stack

    Universal Cocoa Touch Frameworks for iOS8 – (Remix)

    Adding relationships in NSManagedObjectModel to programmatically created NSEntityDescription

    <强>目标-C:

        NSManagedObjectModel * listModel = [[[NSManagedObjectModel alloc] initWithContentsOfURL:[self listModelURL]] mutableCopy];
        NSManagedObjectModel * notesModel = [[[NSManagedObjectModel alloc] initWithContentsOfURL:[self notesModelURL]] mutableCopy];
    
        NSEntityDescription * listEntity = [listModel.entitiesByName objectForKey:NSStringFromClass([JBListItemMO class])];
    
        // The framework name is prepended to the class name. Remove it before getting the note's entityDescription.
        NSString * noteClassName = [NSStringFromClass([JPSNoteMO class]) componentsSeparatedByString:@"."].lastObject;
        NSEntityDescription * noteEntity = [notesModel.entitiesByName objectForKey:noteClassName];
    
        NSRelationshipDescription * whichListRelationship = [[NSRelationshipDescription alloc] init];
        whichListRelationship.minCount = 0;
        whichListRelationship.maxCount = 1;
        whichListRelationship.optional = NO;
        whichListRelationship.name = @"whichList";
        whichListRelationship.destinationEntity = listEntity;
        whichListRelationship.deleteRule = NSNullifyDeleteRule;
    
        NSRelationshipDescription * notesRelationship = [[NSRelationshipDescription alloc] init];
        notesRelationship.ordered = NO;
        notesRelationship.maxCount = 0;
        notesRelationship.minCount = 0;
        notesRelationship.optional = YES;
        notesRelationship.name = @"notes";
        notesRelationship.destinationEntity = noteEntity;
        notesRelationship.deleteRule = NSCascadeDeleteRule;
        notesRelationship.inverseRelationship = whichListRelationship;
    
        whichListRelationship.inverseRelationship = notesRelationship;
    
        listEntity.properties = [listEntity.properties arrayByAddingObject: notesRelationship];
        noteEntity.properties = [noteEntity.properties arrayByAddingObject: whichListRelationship];
    
        self.managedObjectModel = [NSManagedObjectModel modelByMergingModels:@[listModel, notesModel]];
    

    当我完成CoreDataStack类的转换后,我会发布Swift 3代码。

相关问题