gpt4 book ai didi

objective-c - EXC_BAD_ACCESS 在启用 ARC 的情况下实现 NSOutlineViewDataSource

转载 作者:搜寻专家 更新时间:2023-10-30 20:25:42 26 4
gpt4 key购买 nike

我正在实现一个简单的文件浏览器(在 NSOutlineView 中)并且在展开我的根节点时遇到了 EXC_BAD_ACCESS。我的 NSOutlineViewDataSource 返回子项如下:

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
if (!item) {
// Root node
return @"Files";
}
NSFileManager *manager = [NSFileManager defaultManager];

NSError *error = nil;
return [[manager contentsOfDirectoryAtPath:@"/" error:&error] objectAtIndex:index];
}

从这个方法返回的 NSString 正在被自动释放,当 AppKit 代码在这里调用时:

- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item {
NSString *identifier = [item isEqualToString:@"Files"] ? @"HeaderCell" : @"DataCell";
NSTableCellView *cell = [outlineView makeViewWithIdentifier:identifier owner:self];
cell.textField.stringValue = item;
return cell;
}

item 已经消失了。这是项目生命周期的 Instruments 屏幕截图:

Instruments Screenshot

我不确定我做错了什么 - 我不能显式保留任何东西(我也不应该!)因为启用了 ARC,但子项目仍然丢失。

编辑:实际崩溃的堆栈跟踪:

   0 CoreFoundation -[__NSCFString retain]
1 Spark -[SPFileBrowserController outlineView:child:ofItem:] /Users/Craig/projects/Spark/Spark/SPFileBrowserController.m:29
2 AppKit loadItemEntryLazyInfoIfNecessary
3 AppKit -[NSOutlineView _rowEntryForChild:ofParent:requiredRowEntryLoadMask:]
4 AppKit -[NSOutlineView _expandItemEntryChildren:atStartLevel:expandChildren:andInvalidate:]
5 AppKit -[NSOutlineView _expandItemEntry:expandChildren:startLevel:]
6 AppKit -[NSOutlineView _batchExpandItemsWithItemEntries:expandChildren:]
7 AppKit -[NSOutlineView expandItem:expandChildren:]
8 AppKit -[NSOutlineView _doUserExpandOrCollapseOfItem:isExpand:optionKeyWasDown:]
9 AppKit -[NSOutlineView _outlineControlClicked:]
10 AppKit -[NSApplication sendAction:to:from:]
11 AppKit -[NSControl sendAction:to:]
12 AppKit -[NSCell _sendActionFrom:]
13 AppKit -[NSCell trackMouse:inRect:ofView:untilMouseUp:]
14 AppKit -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:]
15 AppKit -[NSControl mouseDown:]
16 AppKit -[NSWindow sendEvent:]
17 AppKit -[NSApplication sendEvent:]
18 AppKit -[NSApplication run]
19 AppKit NSApplicationMain
20 libdyld.dylib start

编辑 2:项目现已附加。编辑 SPFileUtil childrenOfFolder: 的返回值以使用选项 2 进行一致重现。当使用单个 NSString 时总是通过,但当使用 NSFileManager 内容时总是失败。

https://www.dropbox.com/s/lqj5r5ndg0qusak/Spark.zip

崩溃发生在展开根"file"项之后。

最佳答案

直接从文件系统提供大纲 View 内容可能有点不安全,例如,如果从文件系统添加/删除文件会发生什么?更好的方法是缓存文件系统内容并直接从中提供内容。然后您可以确定返回的值来自:

– numberOfRowsInTableView:

匹配您存储的内容(并且在请求不再存在的行时不会出现越界异常)。

要真正有趣,您可以观察文件系统并刷新缓存,然后在对它进行更改时刷新大纲 View 。

更新:除此之外,作为缓存的一部分,您通常会使用如下数据结构在大纲 View 中构建节点树:

@interface OutlineNode : NSObject
{
id _item;
OutlineNode * __weak _parentNode;
NSMutableArray *_childNodes;
}

并且可以在OutlineView中设置具体的节点,例如:

- (BOOL)outlineView:(NSOutlineView *)outlineView
isItemExpandable:(id)item
{
if (item == nil)
return YES;

OutlineNode *node = (OutlineNode *)item;
return node.parentNode == nil;
}

关于objective-c - EXC_BAD_ACCESS 在启用 ARC 的情况下实现 NSOutlineViewDataSource,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13348524/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com