Iphone uiimage的内存泄漏

Iphone uiimage的内存泄漏,iphone,Iphone,我的图像被严重泄露了。你能帮帮我吗 -(UIImage*)getImage{ return [self getForrrrImage]; } -(UIImage*)getForrrrImage{ NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init]; UIImage *imageResult=nil; if(index>=0 && index<[imagesPatchs count]){

我的图像被严重泄露了。你能帮帮我吗

-(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;  

}
-(UIImage*)获取图像{
return[自获取ForrRimage];
}
-(UIImage*)GetForrRimage{
NSAutoreleasePool*池=[[NSAutoreleasePool alloc]init];
UIImage*imageResult=nil;
如果(索引>=0&&indexHeavy内存泄漏
[数据发布];
[泳池排水沟];
返回图像结果;
}

现在,根据所采用的代码路径,您将返回大量自动删除和保留的对象。以下是修复方法:

首先,在
createImageFromFile:
中,您需要执行
返回[imageResult autorelease];
并从
GetForrRimage
方法中删除
[imageResult release];

接下来,您有大量的
imageResult=[UIImage alloc];
,这是错误的,因为您正在分配但没有初始化对象。此外,您也不会自动释放它。如果没有图像,则只需返回
nil

请记住:您应该始终返回自动释放的对象,除非:

  • 您的方法以
    new
  • 您的方法以
    alloc
  • 您的方法包含单词
    copy
    (如
    mutableCopy
在所有其他情况下,都希望返回非所有权(即自动删除)对象。而到目前为止,坚持这一点只是为了让您的生活更轻松(以及所有使用您的代码的人的生活更轻松),在使用iOS 5的自动引用计数时,必须遵守这些约定。因此,除非您喜欢以后的大量调试和重构,否则您需要确保您的代码遵守这些规则

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

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

只需检查每个
createImageFromFile
,并确保随后发布,因为您没有这样做


其次,您应该使用NSString的便利方法,如[NSString stringWithFormat],则不必每次都分配一个NString。这将为您省去麻烦。

您已在
GetForrRimage
中分配了
imageResult
,并且
createImageFromFile
返回了没有匹配释放的对象。如果需要从方法返回分配的对象,请向其发送自动释放消息

MyObject *obj = [[MyObject alloc] init];
return [obj autorelease];
请注意,您不能在方法中释放
obj
,因为您需要调用者中的对象。这就是使用自动释放的原因。如果将来需要,您可以在调用者中保留返回的自动释放的
obj

而不是

[[UIImage alloc] initWithData: data];
你可以试试

[UIImage imageWithData: data];
这将确保您不需要关心释放对象,因为您使用的类方法已经为您初始化了映像

然后你也应该拍摄自动释放,比如

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

举个例子。

GetForrRimage这是GRRRRRAT?不妨猜测一下。为什么需要在每个函数中编写NSAutoreleasePool*pool=[[NSAutoreleasePool alloc]init];没有……但我仍在搜索我的答案……请帮助我我使用了[imageResult autorelease]。但它会导致崩溃。您可能需要保留返回的对象。请阅读《内存管理编程指南()。阅读此指南几小时可能会节省数百小时。