2011-12-16 81 views
0

我有一個代碼,每次用戶移動滑塊並將其添加到子圖層時,都會生成新圖像。它工作,除了泄漏內存。我保留的我不應該這樣做?不過,我想我釋放一切,因爲我應該:iPhone創建自定義圖像導致內存泄漏

UISlider *slider = (UISlider *)sender; 
int progressAsInt = (int)(slider.value); 

//add moon mask 
UIGraphicsBeginImageContextWithOptions(CGSizeMake(400, 400), NO, 1); 
CGContextRef contextRef = UIGraphicsGetCurrentContext(); 
CGContextSetRGBFillColor(contextRef, 0, 0, 0, 0.8); 
CGContextSetRGBStrokeColor(contextRef, 0, 0, 0, 0.8); 
int tempx = progressAsInt; 
int x = tempx; 
if (x < 0) { 
    isHigherThanHalf = YES; 
    x = -tempx; 
} 
else { 
    isHigherThanHalf = NO; 
} 

CGContextSaveGState(contextRef); 
BOOL onlyDrawTopHalf = isHigherThanHalf; 
CGFloat halfMultiplier = onlyDrawTopHalf ? -1.0 : 1.0; 
CGRect ellipse = CGRectMake(200-x/2, 0, 0+x, 400); 

CGRect clipRect = CGRectOffset(ellipse, halfMultiplier * ellipse.size.width/2, 0); 
CGContextClipToRect(contextRef, clipRect); 
CGContextFillEllipseInRect(contextRef, ellipse); 
CGContextRestoreGState(contextRef); 

CGContextSaveGState(contextRef); 
onlyDrawTopHalf = !onlyDrawTopHalf; 
halfMultiplier = onlyDrawTopHalf ? -1.0 : 1.0; 
ellipse = CGRectMake(0, 0, 400, 400); 

clipRect = CGRectOffset(ellipse, halfMultiplier * ellipse.size.width/2, 0); 
CGContextClipToRect(contextRef, clipRect); 
CGContextFillEllipseInRect(contextRef, ellipse); 
CGContextRestoreGState(contextRef); 

UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
NSData *data = (NSData *)CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage)); 
//must free pixels 
free(pixels); 
pixels = (Byte *)[data bytes]; 


CGImageRef imageRef = image.CGImage; 

// create a new image from the modified pixel data 
size_t width     = CGImageGetWidth(imageRef); 
size_t height     = CGImageGetHeight(imageRef); 
size_t bitsPerComponent   = CGImageGetBitsPerComponent(imageRef); 
size_t bitsPerPixel    = CGImageGetBitsPerPixel(imageRef); 
size_t bytesPerRow    = CGImageGetBytesPerRow(imageRef); 

CGColorSpaceRef colorspace  = CGColorSpaceCreateDeviceRGB(); 
CGBitmapInfo bitmapInfo   = CGImageGetBitmapInfo(imageRef); 
CGDataProviderRef provider  = CGDataProviderCreateWithData(NULL, pixels, [data length], NULL); 

CGImageRef newImageRef = CGImageCreate (
             width, 
             height, 
             bitsPerComponent, 
             bitsPerPixel, 
             bytesPerRow, 
             colorspace, 
             bitmapInfo, 
             provider, 
             NULL, 
             false, 
             kCGRenderingIntentDefault 
             ); 
// the modified image 
UIImage *newImage = [UIImage imageWithCGImage:newImageRef]; 
sublayer2.contents = (id)[newImage CGImage]; 
[self.view.layer addSublayer:sublayer2]; 
// cleanup 
[data release]; 
CGColorSpaceRelease(colorspace); 
CGDataProviderRelease(provider); 
CGImageRelease(newImageRef); 

我已經添加[數據發佈],但似乎仍然有一些泄漏。我發現,除了[數據發佈],我需要通過調用 來關閉我的圖像上下文UIGraphicsEndImageContext();我不知道如何使用UIGraphicsEndImageContext。 泄漏已停止。

+0

出於好奇,分析儀會說什麼嗎?轉至產品 - >分析。 – Luke 2011-12-16 11:56:04

回答

0
NSData *data = (NSData *)CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage)); 

數據對象未被釋放。您有時會使用autorelease圖像對象導致memoryWarning。

UIImage *newImage = [UIImage imageWithCGImage:newImageRef]; 

最好是手動創建對象,然後在完成對象時釋放。因爲我們不知道何時自動還原池會流失。

+1

事實上,NSData對象似乎泄漏,但是,我不確定我是否同意下一條語句:「我們永遠不知道何時autorelease池將被耗盡」。事實上,我們知道,在每個運行循環週期結束時它會被排空。這使得在相同的範圍內使用它非常安全。 – 2011-12-16 12:30:23