我正在编写一个带有基于视图的 NSTableView 的沙盒 ARC 应用程序,该应用程序接受拖放文件(NSURL
s)。NSTableViewDelegate
我在以下方法中遇到了一些重大的奇怪现象:
- (NSView *)tableView:(NSTableView *)tv
viewForTableColumn:(NSTableColumn *)tc
row:(NSInteger)row
{
// `files' is an NSMutableArray* ivar containing NSURLs
// that have been dropped into this table
NSURL *url = [files objectAtIndex:row];
NSString *fileName = [url lastPathComponent];
NSImage *icon = [self iconForURL:url];
NSTableCellView *view = [tv makeViewWithIdentifier:[tc identifier] owner:self];
[[view textField] setStringValue:fileName];
[[view imageView] setImage:icon];
return view;
}
我可以将一个文件拖到表格视图中,它可以正确显示。当我拖动第二个文件时,出现此错误:
*** 取消拖动,因为在拖动会话期间引发了异常 'NSRangeException'(原因 '*** -[__NSArrayM insertObject:atIndex:]: index 1 beyond bounds for empty array')
通过调试器,我发现files
在调用makeViewWithIdentifier:owner:
. 我认为这是我不理解的 ARC 的某些方面,但在我看来,该对象强烈引用了它自己的 ivar(默认情况下);它怎么能从我下面被释放和重新创造出来?
我想出了两个技巧来解决这个问题:
- 将 ivar 作为表格单元格视图的所有者传递(希望在未来的版本中它将继续保持强引用);或者
- 创建一个局部变量以指向 ivar 的对象并将 ivar 重新分配给旧对象(这显然是浪费,因为它同时创建了一个替换数组)。
我在这里想念什么?这些变通方法应该不是必需的。