我在为NSOutlineView创建单独的Controller类时遇到问题。

我创建了一个名为LTSidebarViewController的新类,并在MainMenu.xib文件中向“工作台”添加了一个Object并将其链接到我的LTSidebarViewController类。我还将委托和数据源设置为链接到MainMenu.xib中的NSOutlineView。

我想做的是从AppDelegate文件的- (void)applicationDidFinishLaunching:(NSNotification *)aNotification中创建此类的实例,当我这样做时,我想传入App Delegate的managedObjectContext。因此,我在init中创建了一个自定义的LTSidebarViewController方法,如下所示:

-(id)initWithManagedObject:(NSManagedObjectContext*)managedObject{

    self = [super init];
    if (self) {
        self.managedObjectContext = managedObject;

        NSFetchRequest *subjectsFetchReq = [[NSFetchRequest alloc]init];
        [subjectsFetchReq setEntity:[NSEntityDescription entityForName:@"Subject"
                                                inManagedObjectContext:self.managedObjectContext]];

        subjectsArray = [self.managedObjectContext executeFetchRequest:subjectsFetchReq error:nil];

        _topLevelItems = [NSArray arrayWithObjects:@"SUBJECTS", nil];

        // The data is stored in a  dictionary
        _childrenDictionary = [NSMutableDictionary new];
        [_childrenDictionary setObject:subjectsArray forKey:@"SUBJECTS"];

        // The basic recipe for a sidebar
        [_sidebarOutlineView sizeLastColumnToFit];
        [_sidebarOutlineView reloadData];
        [_sidebarOutlineView setFloatsGroupRows:NO];

        // Set the row size of the tableview
        [_sidebarOutlineView setRowSizeStyle:NSTableViewRowSizeStyleLarge];

        // Expand all the root items; disable the expansion animation that normally happens
        [NSAnimationContext beginGrouping];
        [[NSAnimationContext currentContext] setDuration:0];
        [_sidebarOutlineView expandItem:nil expandChildren:YES];
        [NSAnimationContext endGrouping];

        // Automatically select first row
        [_sidebarOutlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:1] byExtendingSelection:NO];
    }
    return self;

}


我在此类中还具有所有必需的方法,例如- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item等。

在App Delegate的- (void)applicationDidFinishLaunching:(NSNotification *)aNotification方法中,我具有以下内容:

    LTSidebarViewController *sidebarViewController = [[LTSidebarViewController alloc] initWithManagedObject:self.managedObjectContext];


我的问题是,这不起作用,我没有收到任何错误,并且该应用程序正在运行,但是NSOutlineView中没有显示任何数据。

现在,从我可以说出的问题是,当MainMenu.xib文件最初加载时,它会自动创建我的LTSidebarViewController类的实例并调用它的init方法,但是因为我的init方法没有执行该应用程序所要做的任何事情,完成正确的启动。

我在这里采用正确的方法吗?简单来说,我要寻找的是拥有一个单独的文件,该文件用作NSOutlineView的数据源。

最佳答案

在使用NSOutlineView时,我通常会进行大量日志记录以了解正在发生的情况。我可能会做类似以下的事情(也许您已经做过一些):

通过记录它来确保您确实在subjectArray中有数据,例如

NSLog(@"subjectsArray");
NSLog(@"%@", subjectsArray);


确保已从AppDelegate.m文件中的NSOutlineView Datasource Methods实现了NSOutlineView Datasource协议方法,并且它们正在返回适当的数据。


如果需要帮助来实现这些,请尝试使用Source Lists and NSOutlineView之类的教程。
通常,我通常在每个NSOutlineView数据源方法中使用NSLog语句来确保它们被调用,并且我了解每个期望和返回的结果。


通过记录它们,确保您的initWithManagedObject:(NSManagedObjectContext *)managedObject方法中的委托和数据源出于某种原因不为零。

NSLog(@"datasource: %@", [self datasource]);
NSLog(@"delegate: %@", [self delegate]);


如果由于某种原因发现它们为零,则可以手动设置它们以确保这不是问题,例如在initWithManagedObject中:

[self setDelegate: [NSApp delegate]];
[self setDatasource: [NSApp delegate]];


至于这是否是“正确”的方法:从您的代码中我不清楚您是否打算sideBarController既是delegate又是datasource还是AppDelegate是否在扮演这些角色。显然,您需要在适当的文件中实现delegatedatasource协议。您肯定可以让AppDelegate担任那些角色,尽管让sideBarController这样做更有意义。

小提示:有时我会直接从支持文件的目录访问AppDelegate的managedObjectContext,例如

-(NSManagedObjectContext *)managedObjectContext
{
return [[NSApp delegate] managedObjectContext];
}


而不是手动将managedObjectContext传递给每个文件。

关于objective-c - 为NSOutlineView创建 Controller ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13478635/

10-15 11:57