使用NSOutlineView和stringWithFormat的EXC_BAD_ACCESS

时间:2013-06-19 00:52:37

标签: objective-c cocoa exc-bad-access nsoutlineview

当我的NSOutlineView项目展开时,我遇到了错误的访问错误。在NSStrings分配stringWithFormat:时,展开大纲时会出现EXC_BAD_ACCESS错误。当它们被@“string”形式的字符串替换时,没有错误。

我假设某些东西正在与ARC一起发布,但我不知道如何阻止它发生。什么看起来不正常?

-(NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {

    if(!item)
        return [_characterList count];
    else if( [item isKindOfClass:[Character class]] )
        return 3;

    return 0;

}

-(BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {

    if( [item isKindOfClass:[Character class]] )
        return YES;

    return NO;

}

-(id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {

    if (!item)
        return (Character*)[_characterList objectAtIndex:index];
    else {

        NSLog(@"%@", item);

        Character *characterItem = (Character*)item;

        switch (index) {
            case 0:
                return [NSString stringWithFormat:@"Api key: %@", [characterItem apiKey]];
                break;
            case 1:
                return [NSString stringWithFormat:@"Access Mask: %@", [characterItem mask]];
                break;
            case 2:
                return @"Last Updated: today";
                break;
            default:
                break;
        }

    }

    return nil;

}

-(id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {

    if([item isKindOfClass:[Character class]])
        return [(Character*)item name];
    else
        return item;

    return nil;

}

1 个答案:

答案 0 :(得分:3)

我提出的解决方案(但不是特别喜欢)。替换outlineView:objectValueForTableColumn:byItem:使用以下代码。

-(NSView*)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item {

NSTableCellView *cell = [outlineView makeViewWithIdentifier:@"characterColumn" owner:self];

    if([item isKindOfClass:[Character class]]) {
        [cell.textField setStringValue:[item name]];
    } else if([item isKindOfClass:[NSString class]]) {
        [cell.textField setStringValue:item];
    }

    return cell;

}

基本上它的作用正是我期望的单元格代码所做的,但它似乎保留了正确的东西。来自群众的任何见解?

编辑:这是交易。 NSOutlineView的dataSource委托方法对所有权有点特别。通常使用香草NSTableView,这不是你需要处理的东西,因为没有多个级别的项目。基本上,您需要创建所有对象以便在其他地方显示,并确保它们在其他地方的内存中进行管理,因为NSOutlineViewDataSource不会为您执行任何操作。