【问题标题】:NSString leaking even with release at the right place (I guess)?即使在正确的位置释放 NSString 也会泄漏(我猜)?
【发布时间】:2011-04-15 08:00:58
【问题描述】:

当我使用 Instruments 分析以下代码时,它报告了变量 imageName 的泄漏:

//loadImagesFromPotatoesIndexesArray
-(void) loadImagesFromPotatoesIndexesArray{

    //Load Textures from Disk
    textures = [[NSMutableArray alloc] init];
    //NSArray *masks = [[NSArray alloc] initWithArray:mainDelegate.masksArray];

    for (int i = 0;i<[potatoesIndexesArray count];i++){ 

        int imageNumber = [[potatoesIndexesArray objectAtIndex:i]intValue];

        NSString *imageName = [[NSString alloc] initWithFormat:@"texture%d",imageNumber];

        UIImage *image = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:imageName ofType:@"png"]];

        NSArray *pics = [[NSArray alloc] initWithObjects:
                         [self maskImage:image withMask:[mainDelegate.masksArray objectAtIndex:i]],
                         [self maskImage:image withMask:[mainDelegate.masksArray objectAtIndex:i]],
                         imageName, 
                         nil]; 

        [textures addObject:pics];

        [image release];
        [imageName release];
        [pics release];
    }
}

[potatoesIndexesArray count] = 16,所以我有 16 次 NSCFString 泄漏......但对我来说,代码尊重内存管理......显然不是! 我做错了什么?

【问题讨论】:

  • 看起来正确。你在你的设备上测试了吗?使用模拟器时,有时会出现“假”泄漏。

标签: iphone memory-leaks nsstring


【解决方案1】:

您永远不会释放“纹理”数组。它仍然拥有一切。

【讨论】:

    【解决方案2】:

    loadImagesFromPotatoesIndexesArray 在您的代码中多久调用一次?如果被多次调用,则原始数组中的所有值都将被泄露,因为您在将textures 替换为新数组之前没有正确释放它。

    如果它 被多次调用,这应该可以解决问题:

    // load textures from disk
    [textures removeAllObjects];
    //NSArray *masks = [[NSArray ...
    
    for (int i=0; ...
    

    【讨论】:

      【解决方案3】:

      如果认为当您在 pics 数组中添加 imageName 时,它​​会保留它;-) (我认为它回答了你的问题)

      但是,你为什么要在这里进行分配? 为什么不做类似的事情

      [ NSString stringWithFormat:@"" ]
      ?

      祝你好运!

      【讨论】:

      • 是的,如果您向数组中添加某些内容,它将被保留。这与泄漏不同,因为您仍然可以通过数组访问它。
      • +stringWithFormat 将添加到自动释放池中。使用 -initWithFormat 意味着可以在自动释放池耗尽之前释放字符串,从而节省内存。我不知道这对这段代码是否至关重要,但有理由使用 -init... 而不是 +string...
      【解决方案4】:

      这是一个复杂的问题。你分配了imageName,所以retainCount为1,然后你把它添加到一个数组中,retain count为2,当你释放imageName时,retain Count又为1。然后,如果您还释放 pics 数组,一切都会好起来的。但是你的图片数组被添加到纹理中,然后pics被释放,所以你的图片retainCount仍然是1。你的imageName被泄露了。但是,如果你释放textures 数组,一切都会好起来的

          NSString *imageName = [[NSString alloc] initWithFormat:@"texture%d",imageNumber];
      
         NSArray *pics = [[NSArray alloc] initWithObjects:
                           [self maskImage:image withMask:[mainDelegate.masksArray objectAtIndex:i]],
                           [self maskImage:image withMask:[mainDelegate.masksArray objectAtIndex:i]],
                           imageName, 
                           nil]; 
      
          [imageName release];
      

      【讨论】:

      • 我必须假设他在使用纹理数组后会正确处理它。你的解释是错误的,而不是他看到泄漏的原因。
      • 根本问题可能是没有释放纹理数组。如果纹理数组被释放,它包含的所有东西都将被释放(包括图片数组,它将释放图像名称)。
      • 是的,我应该仔细解释那部分
      猜你喜欢
      • 2021-11-19
      • 1970-01-01
      • 2015-03-04
      • 2011-05-15
      • 2018-07-23
      • 1970-01-01
      • 1970-01-01
      • 2014-08-10
      • 2011-09-23
      相关资源
      最近更新 更多