gpt4 book ai didi

cocoa - NSOutlineView(源列表)ARC 的 EXC_BAD_ACCESS 错误

转载 作者:行者123 更新时间:2023-12-03 16:32:05 25 4
gpt4 key购买 nike

我有一个启用 ARC 的项目,并且在 IB 中创建了一个窗口,其中包含源列表组件,我认为它只是一个已配置的 NSOutlineView。我正在使用神奇的委托(delegate)方法:

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

我根本找不到任何文档。实现此方法后,我的大纲 View 中将出现根节点,整个模型将在根节点上释放。然后,当我尝试展开根节点时,应用程序立即崩溃,因为模型不再存在。

如果我不使用此方法,我的模型仍然存在,源列表有效,但没有任何单元格出现(可以理解)。我真的没有在这里做任何花哨的事情。

我以前从未遇到过 ARC 的此类问题,但现在已经晚了,所以我有可能做了一些愚蠢的事情,只是看不到它。完整代码如下:

@implementation RLListController

- (void)awakeFromNib
{
RLPerson *stan = [[RLPerson alloc] initWithName:@"Stan"];
RLPerson *eric = [[RLPerson alloc] initWithName:@"Eric"];
RLPerson *ken = [[RLPerson alloc] initWithName:@"Ken"];
RLPerson *andrew = [[RLPerson alloc] initWithName:@"Andrew"];
RLPerson *daniel = [[RLPerson alloc] initWithName:@"Daniel"];
RLPerson *aksel = [[RLPerson alloc] initWithName:@"Aksel"];

[stan addChild:eric];
[stan addChild:ken];
[stan addChild:andrew];

[ken addChild:daniel];
[daniel addChild:aksel];

self.people = [@[stan] mutableCopy];
}

#pragma mark - Source List dataSource

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
{
RLPerson *person = item;
return (item != nil) ? [person.children count] : [self.people count];
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
{
RLPerson *person = item;
return (item != nil) ? [person.children count] > 0 : YES;
}

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
{
RLPerson *person = item;
return (item != nil) ? [person.children objectAtIndex:index] : [self.people objectAtIndex:index];
}

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
RLPerson *person = item;
return person.name;
}

- (id)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item
{
RLPerson *person = item;
NSTableCellView *cell = [outlineView makeViewWithIdentifier:@"DataCell" owner:self];
cell.objectValue = person;
[cell.textField setStringValue:person.name];
return cell;
}

@end


@implementation RLPerson

- (id)initWithName:(NSString *)name
{
self = [super init];
if(self)
{
_name = [name copy];
_children = [[NSMutableArray alloc] initWithCapacity:0];
}
return self;
}

- (void)addChild:(RLPerson *)child
{
[_children addObject:child];
}

- (void)dealloc
{
NSLog(@"dealloc");
}

@end

最佳答案

我刚刚在我的代码中发现了类似的崩溃。我将描述对我来说的原因......我很确定这同样适用于这里,但我还没有测试你的代码。

请注意,如果您有多个 NIB,则可以多次调用 awakeFromNib。我相信如果您的 XIB 文件中的 NSOutlineView 中嵌入了 NSTableCellView 对象,那么当您在 outlineView:viewForTableColumn:item: 中调用 makeViewWithIdentifier:owner: 时会提取这些对象,就会出现这种情况>.

因为您正在 awakeFromNib 中创建模型对象(stan 等),所以它们会在多次调用期间重新创建。每次调用时,ARC 都会清理以前的模型对象,但 NSOutlineView 仍在引用它们,因此当 NSOutlineView 尝试向它们询问更多信息时会崩溃。

解决方法是将模型对象的创建从 awakeFromNib 中移出,也许移到 init 方法中。

更新:

其他一些小问题...我还花了一段时间才找到神奇的 outlineView:viewForTableColumn:item: 方法的文档。由于某种原因,它是 NSOutlineViewDelegate 协议(protocol)的一部分,而不是 NSOutlineViewDataSource 的一部分。我相信,如果您实现此方法,则不需要实现 outlineView:objectValueForTableColumn:byItem:

关于cocoa - NSOutlineView(源列表)ARC 的 EXC_BAD_ACCESS 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18137676/

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