NSOutlineView ObjectValueForTableColumn额外调用触发BAD ACCESS

时间:2014-01-20 03:44:51

标签: objective-c macos core-data nsoutlineview

测试时我发现outlineView:objectValueForTableColumn:byItem:在填充最后一个可见行后一次被调用,导致EXC_BAD_ACCESS错误。

因此,如果我的显示器显示10行,则在第9行填充后再次调用objectValueForTableColumn(没有outlineView:child:ofItem:和outlineView:isItemExpandable:被调用)。额外调用总是在填充最后一个可见行之后发生。

这是我的outlineView代码。我的测试数据集中有2列和114条记录。

// (1)
- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
    if (!item) {
        NSInteger parentCount = [[Parent countParents:self.dataSetID usingManagedObjectContext:self.context] integerValue];
        return parentCount;
    }
    Parent *thisParent = item;
    NSInteger childCount = [[thisParent.child allObjects] count];
    return childCount;
}

// (2)
- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
    NSArray *parentArray = [Parent parentData:self.dataSetID usingManagedObjectContext:self.context];
    Parent *thisParent = [parentArray objectAtIndex:index];
    if (!item) {
        return thisParent;
    }
    NSArray *children = [NSArray arrayWithObject:[thisParent.child allObjects]];
    Child *thisChild = [children objectAtIndex:index];
    return thisChild;
}

// (3)
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
    if ([item isKindOfClass:[Parent class]]) {
        Parent *thisParent = item;
        if ([[thisParent.child allObjects] count] > 0) {
            return YES;
        }
    }
    return NO;
}

// (4)
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
    if (!item) {
        return nil;
    }
    if ([tableColumn.identifier isEqualToString:@"column1"]) {
        if ([item isKindOfClass:[Parent class]]) {
            Parent *thisParent = item;
            return thisParent.name;
        }
        Child *thisChild = item;
        return thisChild.name;
    }
    // This is column2
    if ([item isKindOfClass:[Parent class]]) {
        Parent *thisParent = item;
        return thisParent.age;
    }
    Child *thisChild = item;
    return thisChild.age;
}

我注意到这些方法按顺序调用:1,2,3,4,4,2,3,4,4 ...填充两列NSOutlineView。对于最后一个可见行,顺序为:2,3,4,4,4,最后一次调用方法#4(outlineView:objectValueForTableColumn:byItem :)导致异常。

我无法告诉你传递给方法的值,因为它在通话中断了。即使方法中的第一件事是日志语句,它也不会被执行。

所以我很难过。任何想法为什么这是打破?我是否对实施有所了解?

1 个答案:

答案 0 :(得分:0)

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item 您似乎没有使用item - 您应该返回child item at the specified index of a given item

顺便提一下,你的代码效率很低 - 你应该尽量让它们尽快运行。 你可能想要: -

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
    if (item == nil)
        return [[Parent parentData:self.dataSetID usingManagedObjectContext:self.context] objectAtIndex:index];
    return [[NSArray arrayWithObject:[item.child allObjects]] objectAtIndex:index];
}