核心数据,从新创建的NSManagedObject填充强制关系

时间:2014-06-22 14:34:30

标签: objective-c core-data model-view-controller nsoutlineview nstreecontroller

这应该很容易,有多难。

我有一个基于文档的核心数据应用程序,它具有非常简单的数据模型。

我有一个"节点"具有父/子关系的实体,由NSTreeController控制,并通过NSOutlineView查看。 "节点"也有一个非可选的(到一个)关系到另一个实体类型" nodeProperties"它由NSArrayController管理。我有两个实体的NSManagedObject子类。我的文档类具有绑定到树控制器和阵列控制器实例的出口。

我的问题是如何确保当一个新的"节点"由大纲视图中的用户界面操作创建,它与适当的(预先存在的)nodeProperties对象的关系被填充。

我尝试/考虑的方法:

  1. 让树控制器创建"节点" (来自其add:,addChild:actions)并将关系填充到"节点"中的nodeProperties对象。子类awakeFromInsert方法。麻烦的是我找不到从"节点" s awakeFromInsert中访问任何nodeProperties对象的方法。 "适当的" nodeProperties对象可以从文档类中的方法获得,但是从节点awakeFromInsert方法访问文档对象似乎打破了MVC的原则,并且我已经读过共享文档对象在拖放操作中并不总是安全的(在我的例子中也创建了一个新的节点对象)

  2. 在文档类中编写add:和addChild:action方法,并从最终用户操作而不是树控制器调用这些方法(我的拖放支持也在文档类中)。然后从这些方法中调用树控制器中的add:和addChild:方法,然后在新创建的节点上设置nodeProperties关系。麻烦的是我不知道如何让树控制器给我一个新创建的节点的引用?我尝试使用selectedObjects方法获取父项,然后比较add之前和之后的父项子项以获取新节点。但是孩子的内容在这个时候并没有改变 - 也许这是一个延迟的更新?

  3. 作为2的变​​体,不要使用树控制器添加:/ addChild:方法,而是在文档中创建节点实体对象add:/ addChild:使用树控制器的方法selectedOjects获取父级。我不是很喜欢这个,因为它似乎在树控制器后面做了一些事情,而且我必须setContent:每次我创建根对象。

  4. 我已经考虑过观察新创建节点的创建的可能性,但我不知道应该遵守什么来实现这一点。

  5. 之前有人必须做过这样的事情 - 但我拖网无济于事。非常欢迎所有帮助,建议和指导。

1 个答案:

答案 0 :(得分:0)

好的,经过大量的拖网和实验,答案是3的变体。文档创建新节点,填充其强制关系,添加和addChild操作方法,然后使用方法<将节点插入树控制器/ p>

NSTreeController insertObject:atArrangedObjectIndexPath:

对于那些感兴趣的人,这是我在文档类中的addChild方法。它有我的数据模型中的一些细节

- (IBAction)addChildAction:(id)sender
{
    NSArray *indexPaths = [nodeTreeController selectionIndexPaths];
    NSArray *selectedObjects = [nodeTreeController selectedObjects];
    for (NSUInteger i = 0; i < [indexPaths count]; i++)
    {
        QVXpandNode *parentNode = [selectedObjects objectAtIndex:i];
        if ((parentNode) && ([parentNode.isMaster boolValue])) // can only add nodes under the master node
        {
            QVXpandNode *createdNode = [self createPopulatedNode];
            // Dont belelieve below is safe when >1 selected,
            // since adding a new node will result in the tree paths changing?
            // Hmmm but I do want to support multiple selection addition??
            [nodeTreeController
                insertObject:createdNode
                atArrangedObjectIndexPath:[[indexPaths
                    objectAtIndex:i] indexPathByAddingIndex:[parentNode.children count]]];
        }
    }
}

如果在调用动作之前选择了> 1行,你会发现我不确定是否会将第二个和后来的孩子放在正确的路径上。

由于需要计算最后一个索引路径值,addSibling方法稍微复杂一些,但在其他方面类似。如果有人想看到它,我可以重现它,但是在新树节点中填充强制关系的关键是在文档类中执行它,然后告诉树控制器精确地在树中要插入它的位置。 / p>