如何有效地展平 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?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 flatten_json 递归地展平嵌套的 JSON