【问题标题】:iOS memory leak by dictionary字典的iOS内存泄漏
【发布时间】:2012-02-28 08:11:35
【问题描述】:

我是 iOS 编程新手,我已经为我的客户开发了一个应用程序。但是,当我使用 Instruments 运行应用程序时,似乎存在由字典引起的内存泄漏问题,但如果我释放它,应用程序就会崩溃。我不确定是什么问题。

这是 Instruments 的图片:http://www.flickr.com/photos/71234685@N02/6791493522/in/photostream/

-(void) generateLiquidProductData:(NSArray*) liquidProduct {

    int _count = 52;

    self.liquidProductData = [[NSMutableArray alloc] initWithCapacity:_count];

    for (int i = 0; i < _count; i++){

        float x = i;
        float y;

        if ((liquidProduct != (id)[NSNull null]) && (liquidProduct != nil) && ([liquidProduct count] != 0)) {

            y = [[liquidProduct objectAtIndex:i] floatValue];
            y = round(y * 10000.0f) / 10000.0f;
        }
        else {

            y = 0.0;
            y = round(y * 10000.0f) / 10000.0f;
        }

        NSDictionary* _gotLiquidProduct = [NSDictionary dictionaryWithObjectsAndKeys:
                                                 [NSNumber numberWithDouble:x],X_VAL,
                                                 [NSNumber numberWithDouble:y],Y_VAL,
                                                 nil];
        NSLog(@"This is y %.5f", y);
        [self.liquidProductData addObject:_gotLiquidProduct];
    }
}

【问题讨论】:

  • 行 self.liquidProductData = [[NSMutableArray alloc] initWithCapacity:_count];会导致泄漏:你使用了setter,所以如果保留liquidProductData属性,就会导致泄漏。相反,您可以添加自动释放,或使用自动释放方法 [NSMutableArray arrayWithCapacity:]

标签: objective-c memory-leaks ios4


【解决方案1】:

内存泄漏是由于这一行:

self.liquidProductData = [[NSMutableArray alloc] initWithCapacity:_count];

很可能,该属性被标记为retaincopy(通常是前者)。正确的使用方法是:

self.liquidProductData = [NSMutableArray arrayWithCapacity:_count];

泄漏是因为alloc 返回了一个拥有 引用,您稍后需要该引用到release,但您没有释放它。您现在将其分配给保留实例的属性。 “相对保留计数”现在为 +2。如果您为此属性分配一个新值,旧实例将被释放,但这只会使“相对保留计数”下降到 +1,因此该实例永远不会被释放。这反过来也会泄漏您的字典及其值,因为它们仍然由泄漏的数组保留。

【讨论】:

  • 但是我是第一次使用这个属性所以没有分配我可以给输入吗?
  • [NSMutableArray arrayWithCapacity:] 也在分配,但它返回一个非拥有引用,这意味着您不需要显式释放它。然后将此对象分配给您的属性,并且此属性现在保留它。
  • 哦!,感谢您的宝贵时间,这让我真正理解了这个概念!非常感谢。
【解决方案2】:

每次使用方法时,如果名称开头有 init,则返回的对象永远不会自动释放,因此您有责任释放它。

以“类型”开头的方法,如“arrayWith”、“stringWith”,返回自动释放的对象。

另外一件事,你可以使用静态分析来发现这种泄漏,真的很容易。 Xcode static analysis

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-18
  • 1970-01-01
  • 1970-01-01
  • 2014-06-09
  • 2016-10-16
  • 2014-06-06
相关资源
最近更新 更多