NSOutlineView / NSTreeController在删除后不释放所有模型对象

时间:2013-04-16 07:58:58

标签: cocoa nsoutlineview nstreecontroller retain-cycle

我有一个非常基本的应用:一个NSOutlineView绑定到NSTreeController的窗口。大纲视图显示一个简单的模型对象(TCCard)。我添加了两个按钮,以便我可以在大纲视图中添加和删除模型对象。

查看Instruments(Leaks)中的应用程序我可以看到我添加模型对象的新实例,但是当我从大纲视图中删除它们时,并不会释放所有实例。即使大纲视图中没有更多条目,我的模型对象的两个或三个实例始终保持“活着”。

大纲视图或树控制器是否在幕后进行缓存?代码如下:

#import "TCAppDelegate.h"

#import "TCCard.h"

@implementation TCAppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    TCCard *first = [TCCard new];
    first.title = @"First card";

    // tree controller content is bound to self.cards:
    self.cards = [@[first] mutableCopy]; 
}

- (IBAction)addCard:(id)sender;
{
    TCCard *second = [TCCard new];
    second.title = [NSString stringWithFormat:@"%ld card", self.cards.count];

    [self.treeController addObject:second];
}

- (IBAction)deleteCard:(id)sender;
{
    NSIndexPath *path = [NSIndexPath indexPathWithIndex:self.cards.count - 1];

    [self.treeController setSelectionIndexPath:nil];

    [self.treeController removeObjectAtArrangedObjectIndexPath:path];

    // some model objects continue to live
}

@end

这是一个非常基本的例子。在我的真实应用程序中,这些模型对象非常“沉重”,并且有很多对其他对象的引用。我真的希望当他们从视图中移除时,所有这些都会被释放。

编辑:即使使用Apple的示例代码,也可以重现此问题:https://developer.apple.com/library/mac/#samplecode/DragNDropOutlineView/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008831

在Instruments中的示例中运行并搜索SimpleNodeData。观察实例数,然后从示例应用程序中删除所有节点(通过上下文菜单)。

1 个答案:

答案 0 :(得分:0)

在方法- (IBAction)addCard:(id)sender中,使用[TCCard new]分配新的TCCard对象,它为您提供必须明确释放的对象。由于树控制器会保留您添加到其中的对象,因此应在调用[treeController addObject:]后释放它。 像这样:

- (IBAction)addCard:(id)sender;
{
    TCCard *second = [TCCard new];
    second.title = [NSString stringWithFormat:@"%ld card", self.cards.count];
    [self.treeController addObject:second];
    [second release];
}

提示:使用产品>在Xcode中进行分析,以便在将来解决这类错误。