uiimage的内存泄漏

时间:2011-07-15 07:05:07

标签: iphone

我在UIImage中遇到了严重的泄漏。你能帮我吗?

-(UIImage*)getImage{
  return [self getForrrrImage];
}

-(UIImage*)getForrrrImage{
  NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
  UIImage *imageResult=nil;
  if(index>=0 && index<[imagesPatchs count]){
    NSString *key=[imagesPatchs objectAtIndex:index];
    if(small)
      imageResult=[savedImagesDic objectForKey:key];

    if(!imageResult){
      NSRange range=[key rangeOfString:@"test_bg"];
      if(range.location!=NSNotFound){
        NSString *filePath1;
        if(small){
          NSString *str=[[NSString alloc] initWithFormat:@"%@_small",key];
          filePath1=[[NSBundle mainBundle] pathForResource:str ofType:@"jpg"];
          [str release];
        }
        else
          filePath1=[[NSBundle mainBundle]pathForResource:key ofType:@"jpg"];
        if(filePath1){
          imageResult=[self createImageFromFile:filePath1];
          if(small){
            [savedImagesDic setObject:imageResult forKey:key];

          }
        }
      }

      else{

        NSString *filePath;
        if(small)
          filePath=[[NSString alloc]initWithFormat:@"%@/%@_small.png", DOCUMENTS_FOLDER, key];
        else
          filePath=[[NSString alloc]initWithFormat:@"%@/%@.png", DOCUMENTS_FOLDER, key];

        if([[NSFileManager defaultManager] fileExistsAtPath:filePath]){
          imageResult=[self createImageFromFile:filePath];
          if(small){
            if(imageResult){
              [savedImagesDic setObject:imageResult forKey:key];
              [imageResult release];
            }
            else {
              imageResult=[UIImage alloc];
            }

          }
          else{
            if(!imageResult)
              imageResult=[UIImage alloc];

          }
        }

        [filePath release];
      }
    }
  }
  else
    imageResult=[UIImage alloc];
  [pool drain];

  return imageResult;
} 

-(UIImage*)createImageFromFile:(NSString*)filePath{

  NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];

  UIImage *imageResult=nil;
  NSData *data=[[NSData alloc]initWithContentsOfFile:filePath options:NSUncachedRead error:nil];
  imageResult=[[UIImage alloc] initWithData:data] ;  ----->Heavy memory leak

  [data release];
  [pool drain];
  return imageResult;  

}

4 个答案:

答案 0 :(得分:0)

现在,您将返回一堆自动释放和保留的对象,具体取决于所采用的代码路径。以下是解决这个问题的方法:

首先,在您的createImageFromFile:中,您需要执行return [imageResult autorelease];并从[imageResult release];方法中移除getForrrrImage

接下来,由于您正在分配但未初始化对象,因此您有很多imageResult=[UIImage alloc];错误。你也不自动发布它。如果您没有图像,则只需返回nil

请记住:你总是应该返回自动释放的对象,除了如果:

  • 您的方法以new
  • 开头
  • 您的方法以alloc
  • 开头
  • 您的方法包含单词copy(如mutableCopy

在所有其他情况下,预期返回非拥有(即自动释放)对象。虽然直到现在为止只是为了让你的生活变得更轻松(以及每个使用你的代码的人),但在使用iOS 5的自动引用计数时,强制执行这些约定。所以你想确保你的代码确实如此。遵循这些规则,除非您以后喜欢大量的调试和重构。

我还认为你使用自动释放池是过度的,你应该删除它们(除非你实际调试和测量,发现它们是必要的,以防止内存警告)。无论如何,如果你想坚持使用它们,你需要这样做以保存你的对象在你返回之前不被取消分配:

[imageResult retain];
[pool drain];
[imageResult autorelease];

答案 1 :(得分:0)

只需检查每个createImageFromFile并确保之后释放,因为你没有。

其次,您应该使用NSString的方便方法,如[NSString stringWithFormat],然后您不必每次都分配一个NString。会省你麻烦。

答案 2 :(得分:0)

您已在imageResultgetForrrrImage中分配了createImageFromFile,并返回了没有匹配版本的内容。如果需要从方法返回分配的对象,则向其发送自动释放消息。

MyObject *obj = [[MyObject alloc] init];
return [obj autorelease];

请注意,您无法在方法中释放obj,因为您需要在调用方中使用该对象。这就是使用自动释放的原因。如果您将来需要,可以在调用者中保留返回的自动释放obj

答案 3 :(得分:0)

而不是

[[UIImage alloc] initWithData: data];

您可以尝试

[UIImage imageWithData: data];

这样可以确保您不需要关心释放对象,因为您已经使用了为您初始化Image的类方法。

然后你也应该拍摄自动释放。像

[[[UIImage alloc] initWithData: data] autorelease]

仅作为一个例子。