如何有效地展平 NSOutlineView?

Posted

技术标签:

【中文标题】如何有效地展平 NSOutlineView?【英文标题】:How to efficiently flatten a NSOutlineView? 【发布时间】:2012-08-05 18:20:05 【问题描述】:

我有一个绑定到我的 NSTreeController 的 NSOutlineView。 NSTreecontroller (myTreeController) 的内容使用以下命令设置数据: [self.myTreeController setContent:self.myArrayOfFiles]; 数组的内容由使用 NSTreeNode 子类 (TKnode) 添加的 NSTreeNode 父对象和子对象组成:

[TKnode treeNodeWithRepresentedObject:myRootObject].

这很好用,可以正确显示我的 NSoutlineView。但是当我想遍历 NSOutlineView 的内容时,我需要将其展平并将对象存储在一个数组中。这是我需要一些帮助的地方,因为我拥有的解决方案不是最佳的并且可能容易出错。

我首先使用以下方法返回 NSTreeController 的内容:

 - (NSArray *)rootNodes;

    return [[myTreeController arrangedObjects] childNodes] ;

这将返回一个大小为 1 的 NSTreeControllerTreeNode 数组,该数组包含树结构。然后我使用 childNodes 方法访问树结构的第一层。

- (NSArray *)flattenedNodes

    NSMutableArray *mutableArray = [NSMutableArray array]; 
    for (TKnode *rootnode in [self rootNodes])
        for (TKnode *node in [rootnode childNodes])

            if (![[node representedObject] isLeaf])
                [mutableArray addObjectsFromArray:[self descendants:[node representedObject]]];
            
            else 
                [mutableArray addObject:[[node representedObject] representedObject]];
            
        
    
    DLog(@"My files: %lu",[mutableArray count]);
    return [[mutableArray copy] autorelease];

使用以下方法递归访问children的children:

- (NSArray *)descendants:(TKnode *) node

    NSMutableArray *descendantsArray = [NSMutableArray array]; 
    for (TKnode *mynode in [node childNodes]) 

        [descendantsArray addObject:[mynode representedObject]];

        if (!mynode.isLeaf)
            [descendantsArray addObjectsFromArray:[self descendants:mynode]];
        
    
    return [[descendantsArray copy] autorelease]; // return immutable

这工作并返回一个数组,其中包含我的所有对象,不是 NSTreeNode,而是我感兴趣的对象。但似乎很容易出错,我有时必须在对象上调用两次代表对象才能访问我的对象。这是我应该使用 NSTReeController 和 NSTreeNodes 的方式吗?有没有更好的办法?我首先想使用 NSTreeNode 和 NSTreeController 的原因是为了免费获得一些已经实现的方法,例如排序和排列对象,我习惯于使用 NSTableView。但是我用来访问 NSTreeController 内容的方法似乎不正确?我应该使用arrangedObjects 来获取 NSTReeController 的内容还是应该使用不同的方法?非常感谢任何有关如何正确展平 NSOutlineView 的建议。

谢谢!干杯,特隆德

【问题讨论】:

【参考方案1】:

这个问题原来是一个真正的风滚草(我在一个月内的第二个问题)所以我想跟进一些更多信息。我最终使用上面发布的代码来展平我的 NSOutlineView,因为我找不到更好的选择。当您必须递归遍历未知数量的子文件夹(在我的情况下)时,这似乎是每次达到更深层次时调用 descendants 方法的最佳选择。我发现了一个非常有用的网站,其中包含许多有用的 NSTreeController 扩展 here,它使用的方法与我采用的方法相同。除非有人帮我找出更快更好的算法来扁平化 NSTreeController 的排列对象,否则我相信我会坚持使用这种方法。

干杯,特隆德

更新:在对解决方案提出问题后,我决定发布我的方法,以了解如何展平大纲视图。我希望他能帮助别人。

- (void) flattenOutlineview

    NSMutableArray *nodeArray = [NSMutableArray array];
    [self.myFlattenedFiles removeAllObjects];
    [self.myFlattenedNodes removeAllObjects];
    [self.myIndexDict removeAllObjects];
    [nodeArray removeAllObjects];

    for (SDNode *rootnode in self.rootNodes)
    
        [nodeArray addObject:rootnode];

        [self.myIndexDict setObject:[rootnode indexPath]
                             forKey:[[[rootnode representedObject] representedObject] fullpathL]];

        for (SDNode *node in [rootnode childNodes])
        
            if (node.isLeaf)
                [nodeArray addObject:node];
                 [self.myIndexDict setObject:[node indexPath]
                                 forKey:[[[node representedObject] representedObject] fullPathCopy]];
            
            else 
                [nodeArray addObjectsFromArray:[self descendants:node]];
                [self descendantsIndex:node];
             
         
   
   [self.myFlattenedNodes setArray:[nodeArray copy]];

   for (SDNode *node in self.myFlattenedNodes)
   
       [self.myFlattenedFiles addObject:[[node representedObject] representedObject]];
   

【讨论】:

你能把treeController的演示代码发给我吗?因为我们坚持在这里。我们正在解析目录,需要在树视图中显示。示例应用程序。谢谢。 @user2553442:请参阅我的更新答案。希望这可以帮助。 T 你有这个 NSOutlineView 的示例代码吗.. @Trond Kristiansen 示例代码是什么意思?我刚刚发布了整个方法? T.【参考方案2】:

从我刚刚写的另一个答案中看到了这个链接。如果您将树中的所有内容都展开/显示,这将起作用:

for (NSUInteger row = 0; row < [outlineView numberOfRows]; row++)

    NSTreeNode* node = [outlineView itemAtRow:row];
    [nodeArray addObject:node];

outlineView 的行基本上是一棵扁平的树。您也许可以在迭代时扩展每个项目以获取所有项目。

【讨论】:

以上是关于如何有效地展平 NSOutlineView?的主要内容,如果未能解决你的问题,请参考以下文章

NSOutlineView 侧边栏帮助

在Ruby中递归地展平数组[重复]

如何使用 flatten_json 递归地展平嵌套的 JSON

NSOutlineView 子类崩溃 - NSRangeException

如何在 Python 中完全展平列表? [复制]

将嵌套列表展平为 1 深列表