为什么Instruments会将此报告为内存泄漏?

时间:2009-04-07 18:09:32

标签: objective-c cocoa cocoa-touch

我有一些代码如下:

NSMutableArray *bar = [[NSMutableArray alloc] initWithCapacity:0];
NSMutableDictionary *foo = [[NSMutableDictionary alloc] initWithCapacity:0];
[foo setObject:[NSNull null] forKey:@"yay"];
[bar addObject:foo];

[foo release];

仪器显示foo正在泄漏。我理解为什么会这样。当alloc'd为1时,Foo保留计数。然后当bar addObject的foo时,保留计数变为2.稍后当我释放foo时,它会回落到1.仍然是泄漏。但是,稍后在我的代码中,(在一个单独的方法中,这就是为什么我认为这可能会显示为泄漏)

[bar removeAllObjects];

如果我稍后删除了AllObjects,为什么foo会显示为泄漏?

**注意**

我没有将它包含在我的原始帖子中,但是bar确实正在dealloc方法中发布。

3 个答案:

答案 0 :(得分:3)

鉴于您展示的内容,bar永远不会被释放。调用[bar removeAllObjects]仅删除它包含的对象。相反,您应该在完成[bar release]后致电bar。这将自动释放bar持有的所有对象,并释放条形对象本身。

您声明您了解内存管理概念,因此您可能没有在示例中显示bar

编辑:我认为克雷格在his answer中有正确的想法。避免警告(可能)的一种方法是在类bar方法中分配init。在成员变量方面,我通常发现在initdealloc方法之间保持对称是有益的,这将是一个很好的例子:

- (id)init
{
    if ((self = [super init]) == nil) { return nil; }

    bar = [[NSMutableArray alloc] initWithCapacity:0];

    return self;
}

- (void)dealloc
{
    [bar release];

    [super dealloc];
}

- (void)YourMethod
{
    NSMutableDictionary *foo = [[NSMutableDictionary alloc] initWithCapacity:0];
    [foo setObject:[NSNull null] forKey:@"yay"];
    [bar addObject:foo];
    [foo release];
}

答案 1 :(得分:3)

我认为(而且我认为你也暗示了这种可能性),仪器将其标记为潜在的泄漏,因为它没有足够远远地看到该酒吧将负责用于在所述单独方法中移除/释放其所有对象。

答案 2 :(得分:0)

当调用removeAllObjects时,NSMutableArray应该释放它。您不需要将其释放或添加到自动释放池中。

来自O'Reilly关于记忆管理的主持人:

  

将对象添加到集合时,会保留该对象。从集合中删除对象时,它将被释放。释放集合对象(例如NSArray)也会释放存储在其中的所有对象。

也许仪器中还有其他东西在发生?