乐器说我正在泄漏一根弦,但我找不到它

时间:2011-09-23 14:02:37

标签: iphone objective-c memory memory-leaks

我使用Instruments中的泄漏工具来测试代码,但泄漏工具似乎无法找到泄漏。

在我的代码末尾,NSLog(@"str count:%d",[str retainCount]);的输出是3.为什么?我不会覆盖dealloc。 [a.name retainCount]只有一次 而且我只自动释放str一次。所以str不应该泄漏。

@interface DataMode : NSObject {

    NSString * name;
}

@property (retain) NSString * name;

- initWithName:(NSString * )name_;
@end


@implementation DataMode

@synthesize name;

- initWithName:(NSString * )name_
{
    if ([super init] != nil)
    {
        name = name_;
        return self;
    }
    return nil;
}

@end


- (void) pressed:(id)sender
{
    for( int i = 0;i<10000000;i++)
    {
        NSString * str = [NSString stringWithFormat:@"zhang"];
        DataMode * a = [[DataMode alloc] initWithName:str];
        NSLog(@"a0 count:%d",[a retainCount]);
        NSLog(@"name1 count:%d",[a.name retainCount]);
        NSLog(@"name1 count:%d",[a.name retainCount]);
        NSLog(@"a1 count:%d",[a retainCount]);
        [ a  release];
        NSLog(@"str count:%d",[str retainCount]);
        NSLog(@"str count:%d",[str retainCount]);
    }


}
@end

3 个答案:

答案 0 :(得分:3)

retainCount没用。不要打电话。

找到泄漏是没有用的,因为有更好,更准确,更少误导的工具。

您的代码存在一些问题(但泄漏不是其中之一):

  • NSString *属性应为copy

  • 您不使用该属性在init中设置字符串值,因此DataMode实例不会保留其字符串。

  • 没有dealloc方法

至于保留计数;我很惊讶它是“3”。我希望它是2bazillionsomething,因为它是一个常量字符串(并且常量字符串的stringWithString:只返回字符串)。由于你使用stringWithFormat:,常量字符串变成了非常量字符串。如果您使用了常量字符串或stringWithString:,那就是abazillionsomething(unsigned -1 ... UINT_MAX ...)。

无论如何,你有:

  • +1 stringWithString:
  • +1,用于调用a.name
  • +1,用于调用a.name

总体上+3。

如果Instruments声称泄漏,请发布屏幕截图。

答案 1 :(得分:0)

我引用-retainCount的{​​{3}}:

  

此方法在调试内存管理问题时通常没有价值。因为任何数量的框架对象可能保留了一个对象以保存对它的引用,而同时自动释放池可能在对象上保留任意数量的延迟版本,所以您不太可能从此获取有用信息方法

由于各种原因,保留计数可能为3;如果你找不到泄漏工具的泄漏,你很可能没有泄漏。不要担心保留计数的实际值。

如果你真的对它为什么感兴趣,请回忆一下:

  • 您的DataMode对象a的引用可能会被保留,直到最近的自动释放池耗尽
  • 您仍然在str变量
  • 中持有引用
  • NSString类集群在其他方面做了一些 - 异常莫名其妙 - 在内部缓存内容,所以你可能会看到一些人无处可以保留

答案 2 :(得分:0)

由于您使用方便方法来创建自动释放的str,因此您不会以这种方式使用保留计数来查看确定行为。

检查我对另一个问题的回答并将这些方法添加到DataMode,您应该看到框架何时从自动释放池中释放对象。

Overriding release and retain in your class