2011-07-15 60 views
-1

我在UIImage中发生严重泄漏。你可以帮我吗?内存泄漏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; 

} 
+0

getForrrrImage < - 这么多rrrrrrr的特殊含义? – Raptor

+0

这是肮脏的?不妨猜一猜。 – nil

+0

为什么你需要写NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];在每一个功能? – Maulik

回答

0

而不是

[[UIImage alloc] initWithData: data]; 

你可以尝试

[UIImage imageWithData: data]; 

这将确保你不需要关心释放对象,因为你使用的初始化图片为你的类方法已经。

然后你也应该拍摄autoreleases。像

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

只是一个例子。

0

现在,根据所采用的代码路径,您将返回一大堆自动释放和保留的对象。以下是如何解决这个问题:

首先,在你createImageFromFile:你需要做return [imageResult autorelease];并从getForrrrImage方法去除[imageResult release];

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

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

  • 你的方法用new
  • 你的方法开始alloc
  • 你的方法中包含单词copy(如mutableCopy开始)

在所有其他情况下,它预计非拥有(即自动释放)对象返回。尽管直到现在,坚持这只是为了让你的生活更加简单(以及每个使用你的代码的人),坚持这些约定是在使用iOS 5的自动引用计数时强制执行的。所以你要确保你的代码的确如此遵循这些规则,除非你喜欢以后进行大量的调试和重构。

我也认为你使用autorelease池是矫枉过正,你应该删除它们(除非你实际调试和测量,发现它们是必要的,以防止内存警告)。无论如何,如果你想坚持给他们,你需要做到这一点,以节省您的对象出现释放你回到它之前:

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

刚去通过每一个createImageFromFile,并确保你释放以后,因为你不要“T。其次,你应该使用NSString的便利方法,如[NSString stringWithFormat],那么你不必每次都分配一个NString。会为你节省麻烦。

0

您已在getForrrrImagecreateImageFromFile中分配了imageResult,并返回了没有匹配版本的版本。如果您需要从方法返回一个分配的对象,然后发送一个autorelease消息。

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

请注意,您不能在该方法中释放obj,因为您需要调用方中的该对象。这就是使用autorelease的原因。如果将来您需要,您可以在回话中保留退回的自动发布的obj

+0

嘿我用[imageResult autorelease]。但它给予崩溃 –

+0

您可能需要保留返回的对象。请通过内存管理编程指南(http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html)。几个小时的阅读可能会节省数百小时。 – taskinoor