0

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

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

我要做的是- (void)applicationDidFinishLaunching:(NSNotification *)aNotification在我的 AppDelegate 文件中创建这个类的一个实例,当我这样做时,我想传入 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 的数据源。

4

1 回答 1

1

在使用 NSOutlineView 时,我通常会进行大量的日志记录以弄清楚发生了什么。我可能会做类似以下的事情(也许你已经做了一些):

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

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

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

  • 如果您在实现这些方面需要帮助,请尝试使用Source Lists 和 NSOutlineView等教程。

  • 我通常在每个 NSOutlineView 数据源方法中使用 NSLog 语句,以确保它们被调用并且我了解每个方法的期望和返回。

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

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

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

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

至于这是否是“正确”的方法:我从您的代码中不清楚您是否打算让 sideBarController 既是 thedelegate又是 thedatasource或是否AppDelegate正在服务这些角色。显然,您需要在适当的文件中实现delegatedatasource协议。你当然可以AppDelegate担任这些角色,尽管让你的 sideBarController 这样做似乎更有意义。

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

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

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

于 2012-11-21T03:04:29.493 回答