2010-10-18 110 views
0

目前我使用UIView而不是UIImageview由於大規模圖像中的內存消耗。以下是我使用的相同的代碼。Drawrect導致內存問題

- (void)drawRect:(CGRect)rect 
{ 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextClearRect(context, rect); 
    [myImage drawInRect:rect]; 
} 

-(void) SetImage:(UIImage*) aImage 
{ 
    if(!aImage) 
     return; 

    if(myImage) 
    { 
     [myImage release]; 
     myImage = nil; 
    } 

    myImage = [[[UIImage alloc]initWithCGImage:aImage.CGImage] retain]; 
    [self setNeedsDisplay]; 
} 

每次更新並設置相同的圖像時,這導致了8 MB內存泄漏(使用Instrument檢查)。如果我評論

[self setNeedsDisplay]; 

沒有泄漏。任何人都可以幫助我,如果我做錯了什麼。或誰能幫助我的子類UIImageview處理大規模圖像。

// Calling functions 
    -(void) FitToCardStart 
    { 
     UIImage* temp = ScaleImage([iImageBgView GetImage]); 
     [iImageBgView SetImage:temp]; 
     [temp release]; 
     temp = nil; 

    } 

// ScaleImage 

UIImage* ScaleImage(UIImage* image) 
{ 
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 

    int kMaxResolution = 1800; 

    CGImageRef imgRef = image.CGImage; 
    CGFloat width = CGImageGetWidth(imgRef); 
    CGFloat height = CGImageGetHeight(imgRef); 

    CGAffineTransform transform = CGAffineTransformIdentity; 

    CGRect bounds = CGRectMake(0, 0, width, height); 

    if (width < kMaxResolution || height < kMaxResolution) 
    { 
     CGFloat ratio = width/height; 
     if (ratio > 1) 
     { 
      bounds.size.width = kMaxResolution; 
      bounds.size.height = bounds.size.width/ratio; 
     } 
     else 
     { 
      bounds.size.height = kMaxResolution;  
      bounds.size.width = bounds.size.height * ratio; 
     } 
    } 

    CGFloat scaleRatio = bounds.size.width/width; 
    CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef)); 

    UIImageOrientation orient = image.imageOrientation; 

    switch(orient) 
    { 

     case UIImageOrientationUp: //default 
      transform = CGAffineTransformIdentity; 
      break; 

     default: 
      [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"]; 
    } 

    UIGraphicsBeginImageContext(bounds.size); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextScaleCTM(context, scaleRatio, -scaleRatio); 
    CGContextTranslateCTM(context, 0, -height); 

    CGContextConcatCTM(context, transform); 
    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef); 
    UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext(); 
    UIImage* temp = [[[UIImage alloc] initWithCGImage:imageCopy.CGImage] retain]; 
    CGImageRelease(imgRef); 
    CGContextRelease(context); 

    [pool release]; 

    return temp; 
} 

感謝,

薩加爾

回答

0

我建議不要創建一個新的圖像,但只保留aImage實例。

myImage = [aImage retain]; 

我你絕對必須使一個新的實例,你是在一個非常迂迴的方式這樣做。 複製將是一個更好的選擇。

myImage = [aImage copy]; 
+0

感謝您的回覆,但仍然有同樣的問題。 – 2010-10-18 09:08:54

1
myImage = [[[UIImage alloc]initWithCGImage:aImage.CGImage] retain]; 

還有的冗餘保持在這一行 - 爲你分配新的UIImage對象(使用+ ALLOC)方法,你不需要額外的保留它。

編輯:ScaleImage方法有同樣的問題與冗餘保留:

// remove extra retain here 
UIImage* temp = [[[UIImage alloc] initWithCGImage:imageCopy.CGImage] retain]; 
// should be 
UIImage* temp = [[UIImage alloc] initWithCGImage:imageCopy.CGImage]; 

和代碼風格的註釋 - 最好是在你的方法名需要返回的對象是什麼內存管理行爲來表示 - 通過你的方法返回的圖像需要被釋放的方法名稱應包含「新」,「黃金」,「複製」,「創造」的東西......

1

你的問題是這樣的一行:

myImage = [[[UIImage alloc]initWithCGImage:aImage.CGImage] retain]; 

alloc已經爲您提供了一個保留的1計數,用你最終的2擋計數是過高的額外retain。刪除retain,一切都會好起來的。

+0

感謝DarkDust的回覆,我用這個做了,但仍然有同樣的問題。 – 2010-10-18 08:00:43

+0

@Sagar,你還可以在你創建aImage的地方發佈代碼並調用SetImage方法嗎? – Vladimir 2010-10-18 08:19:54

+0

@Vladimir我用代碼更新了我的帖子。 – 2010-10-18 09:03:31