2011-02-26 57 views
0

我正在使用此功能來創建我的IPAD應用程序的屏幕截圖。我在我的項目中使用Sparrow框架。 SPDisplayObject使用基於OpenGl-ES的渲染。IPad上使用的OpneGL-ES截圖功能中的內存泄漏在哪裏?

@implementation SPDisplayObject (ScreenshotFromSPDisplayObject) 

- (UIImage *)getImageScreenshot{ 

int WIDTH = 1024; 
int HEIGHT = 768; 

CGSize size = CGSizeMake(WIDTH,HEIGHT); 
//Create un buffer for pixels 
GLuint bufferLenght=size.width*size.height*4; 
GLubyte *buffer = (GLubyte *) malloc(bufferLenght); 

//Read Pixels from OpenGL 
glReadPixels(0,0,size.width,size.height,GL_RGBA,GL_UNSIGNED_BYTE,buffer); 
//Make data provider with data. 
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer, bufferLenght, NULL); 

//Configure image 
int bitsPerComponent = 8; 
int bitsPerPixel = 32; 
int bytesPerRow = 4 * size.width; 
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); 
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault; 
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; 
CGImageRef iref = CGImageCreate(size.width,size.height,bitsPerComponent,bitsPerPixel,bytesPerRow,colorSpaceRef,bitmapInfo,provider,NULL,NO,renderingIntent); 

uint32_t *pixels = (uint32_t *)malloc(bufferLenght); 
CGContextRef context = CGBitmapContextCreate(pixels, WIDTH, HEIGHT, 8, WIDTH*4, CGImageGetColorSpace(iref), kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 

CGContextTranslateCTM(context,0, size.height); 
CGContextScaleCTM(context, 1.0, -1.0); 

CGContextDrawImage(context, CGRectMake(0.0, 0.0, size.width, size.height), iref); 
UIImage* screenshot = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context)]; 

UIGraphicsEndImageContext(); 

//free memory 
CGColorSpaceRelease(colorSpaceRef); 
CGDataProviderRelease(provider); 
CGImageRelease(iref); 
CGContextRelease(context); 
free(buffer); 
free(pixels); 

return screenshot; 
} 

@end 

我這樣使用它從UIViewController中:

@interface 
    UIImageView *screenShot; 
    UIImage *tempImage; 

-(void) deactivePage 
{ 
// attach screenshot 
tempImage = [self.stage getImageScreenshot]; 
screenShot = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,1024,768)]; 
screenShot.image = tempImage; 
[self.view addSubview:screenShot]; 
} 

- (void)dealloc 
{ 
screenShot.image = nil; 
[screenShot removeFromSuperview]; 
[screenShot release]; 
[super dealloc]; 
} 

的UIViewController中被釋放,並aprox的釋放。調用「deactivePage」函數5秒鐘後。 屏幕截圖用於視圖轉換。

以屏幕截圖工作就像一個魅力,但與每個屏幕截圖我的應用程序增長約10 MB所以我可以做到這一點大約15倍,直到應用程序崩潰。

那麼泄漏在哪裏?我堅持.. :-(

+0

您是否使用過儀器檢查什麼被泄漏以及在哪裏? – 2011-02-26 16:46:11

回答

1

在你這樣做getImageScreenshot功能:

UIImage* screenshot = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context)]; 

它創建一個CGImageRef,然後從它創建(autorelease)一個UIImage。 這裏發生的是這個CGImageRef保持活着並且從未被釋放,所以它正在泄漏。

你應該這樣做:


CGImageRef myCGImage = CGBitmapContextCreateImage(context); 
UIImage* screenshot = [UIImage imageWithCGImage:myCGImage]; 
CGImageRelease(myCGImage); 

您是否試過使用Instruments(Leaks或Heapshots)來查看它?你應該看到這些CGImareRef元素仍然活着。

+0

這就是訣竅!我已經使用過儀器/泄漏,但是我沒有看到泄漏..奇怪..但是我對Objective-C很陌生,可能沒有使用Instruments .. – 2011-02-26 18:14:51

0

我沒有看到你在UIViewController中解除分配tempImage時,它的下降

+0

當我使用'[tempImage release];'在dealloc中時,應用程序崩潰:'***由於未捕獲異常'NSInvalidArgumentException'導致應用程序終止,原因:' - [NSCFNumber _isNamed]:無法識別的選擇器發送到實例0x5633c40'' – 2011-02-26 16:57:37