为什么EXC_BAD_ACCESS在这个简单的NSOutlineView数据源中呢?

时间:2014-01-13 00:01:29

标签: cocoa nsoutlineview

这基本上是带有数据源的NSOutlineView的“hello world”。我所做的只是将NSOutlineView拖到MainMenu.xib窗口,将其连接到插座,然后尝试将其数据源设置为一个简单的实现。当我运行它时,我得到Thread 1: EXC_BAD_ACCESS,但调试器中的堆栈跟踪正在帮助我。

(lldb) bt
* thread #1: tid = 0x158e35, 0x00007fff8948d097 libobjc.A.dylib`objc_msgSend + 23, queue = 'com.apple.main-thread, stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
frame #0: 0x00007fff8948d097 libobjc.A.dylib`objc_msgSend + 23
frame #1: 0x00007fff8839e590 AppKit`loadItemEntryLazyInfoIfNecessary + 120
frame #2: 0x00007fff883d3e5f AppKit`-[NSOutlineView _rowEntryForRow:requiredRowEntryLoadMask:] + 77
frame #3: 0x00007fff883d37d1 AppKit`-[NSOutlineView frameOfCellAtColumn:row:] + 323
frame #4: 0x00007fff885d5548 AppKit`-[NSTableView drawRow:clipRect:] + 1154
frame #5: 0x00007fff885d4f7d AppKit`-[NSTableView drawRowIndexes:clipRect:] + 776
...

当我设置断点时,我只看到我的一个方法被调用。 (outlineView:numberOfChildrenOfItem:)这是我的代码。有什么想法吗?

它创建了三个简单的“根”项,并返回值的字符串。根据断点,这绝不会被称为。

在app delegate:

@implementation TmTrkAppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
    _outlineView.dataSource = [[TmTrkOutlineViewDataSource alloc] init];
}

@end

数据来源:

@interface TmTrkOutlineViewDataSource : NSObject <NSOutlineViewDataSource>

@end
...

@interface TmTrkTagItem : NSObject {

}

@end

@implementation TmTrkTagItem {

}

@end

@implementation TmTrkOutlineViewDataSource {
    NSMutableArray *_roots;
}

- (id)init {
    printf("init\n");
    self = [super init];
    if (self) {
        _roots = [[NSMutableArray alloc] init];
        for (int i=0; i<3; i++) {
            id item = [TmTrkTagItem new];
            [_roots addObject:item];
        }
        printf("Created _roots %d.\n", (int)_roots.count);
    }
    return self;
}

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
    if (!item) {
        printf("child: %d ofItem: %s\n", (int)index, [item description].UTF8String);
        return _roots[index];
    }
    return nil;
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
    if (!item) return YES;
    else return NO;
}

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
    if (!item) return _roots.count;
    else return 0;
}

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
    NSString *val = @"Test Value";
    return val;
}

@end

这是一个新项目,在Xcode 5.0.2中,启用了ARC。

1 个答案:

答案 0 :(得分:1)

您的数据源可能会在您创建后立即发布,因为您的应用委托不会保留对它的强引用,而NSOutlineView的dataSource也是一个弱引用。