所以,我想在我的应用程序中使用 NSOutlineView 来显示一个特定的,因为缺乏更好的名称,层次结构。为了解释,下面是它在代码中的样子:我有一个协议,它声明了我想显示的对象使用的一些方法:
@protocol OutlineViewItem <NSObject>
@required -(BOOL)hasChildren; //Tells whether the object has children
@required -(NSInteger)numberOfChildren; //returns 0 if none or number of children
@required -(id)getChildren; //return NSMutableArray containing children
@required -(NSString*)getDisplayableName; //returns a string that would be displayed in NSOutlineView
@end
可以猜到,这些方法应该让我的任务更容易一些。
然后,我有以下对象层次结构(它们都实现了该协议)->
主应用程序包含一个 Project 类的实例,它包含一个 NSMutableArray 的 Subproject 类实例,它包含一个 NSMutableArray 的 SubprojectItem 类实例。
我如何在 Project 类中使用这些协议方法的一个示例(子项目是前面提到的 NSMutableArray:
-(BOOL)hasChildren{
if(subprojects == nil || [subprojects count] < 1){
return NO;
}
return YES;
}
-(NSInteger)numberOfChildren{
if(subprojects == nil){
return 0;
}
return [subprojects count];
}
-(id)getChildren{
return subprojects;
}
-(NSString*)getDisplayableName{
return name;
}
Subproject 和 SubprojectItem 类以类似的方式实现这些方法。
在我的应用程序中,我定义了主窗口类(ProjectWindow)来实现 NSOutlineViewDataSource 和 Delegate 协议,并将 NSOutlineView 的数据源和委托绑定到 ProjectWindow。
在 ProjectWindowClass 中,我实现了如下方法:
- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
{
return item == nil ? project : [item getChildren];
//if I understand it correctly, it return the children of a given node.
//if item is nil, it should return the root, that is, project, or the children of item.
}
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
{
return item == nil? YES : [item hasChildren];
//Same as above: project is expendable, other nodes can be expanded if contain children
}
- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
{
return item == nil? 1 : [item numberOfChildren];
//Same as above: there's 1 project, or it returns num of children;
}
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
return item == nil ? @"ROOT" : [item getDisplayableName];
//I think that's what is going to be displayed in NSOutlineView, next to the expendable arrow
}
但是,当我尝试运行它时,遇到了以下异常:
2013-08-23 22:45:12.930 myProject[1903:303] -[__NSArrayM hasChildren]: unrecognized selector sent to instance 0x101a16f30
如果我了解整个 NSOutlineViewDataSource,它应该返回根项,如果使用 item == nil 请求,如果 item != nil 则返回 item 的子项。但是,虽然我认为它应该是这样的,但它不起作用,应用程序挂起。
那么,我应该如何实现所有这些数据源方法以使其按预期工作?