Где утечка памяти в этой функции снимка экрана OpneGL-ES, используемой на iPad? - PullRequest
0 голосов
/ 26 февраля 2011

Я использую эту функцию для создания скриншотов моего приложения IPAD.Я использую Sparrow Framework в своем проекте.SPDisplayObject использует рендеринг на основе OpenGl-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.5 секунд после вызова функции deactivePage.Снимок экрана используется для перехода при просмотре.

Съемка снимков экрана выглядит как обаяние, но с каждым снимком экрана мое приложение растет примерно на 10 МБ, поэтому я могу делать это примерно 15 раз, пока приложение не падает.

Так где же утечка?Я застрял ..: - (

Ответы [ 2 ]

1 голос
/ 26 февраля 2011

В функции getImageScreenshot вы делаете это:

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

, которая создает CGImageRef, а затем создает (автоматически выпускает) UIImage из него.Здесь происходит то, что этот CGImageRef остается живым и никогда не выпускается, поэтому он протекает.

Вместо этого вам следует сделать следующее:


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

Вы пытались просмотреть его с помощьюИнструменты (утечки или кучи)?вы должны увидеть эти элементы CGImareRef еще живыми.

0 голосов
/ 26 февраля 2011

Я не вижу, где вы освобождаете tempImage в UIViewController при его падении.

...