Хорошо, у меня есть мир трудности, отслеживающий эту утечку памяти. При запуске этого сценария я не вижу утечки памяти, но мой объектalloc поднимается. Инструменты указывают на CGBitmapContextCreateImage> create_bitmap_data_provider> malloc, это занимает 60% моего объекта allococ.iPhone - UIImage Leak, CGBitmapContextCreateImage Leak
Этот код вызывается несколько раз с помощью NSTimer.
//GET IMAGE FROM RESOURCE DIR
NSString * fileLocation = [[NSBundle mainBundle] pathForResource:imgMain ofType:@"jpg"];
NSData * imageData = [NSData dataWithContentsOfFile:fileLocation];
UIImage * blurMe = [UIImage imageWithData:imageData];
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
UIImage * scaledImage = [blurMe _imageScaledToSize:CGSizeMake(blurMe.size.width/dblBlurLevel, blurMe.size.width/dblBlurLevel) interpolationQuality:3.0];
UIImage * labelImage = [scaledImage _imageScaledToSize:blurMe.size interpolationQuality:3.0];
UIImage * imageCopy = [[UIImage alloc] initWithCGImage:labelImage.CGImage];
[pool drain]; // deallocates scaledImage and labelImage
imgView.image = imageCopy;
[imageCopy release];
Ниже представлена функция размытия. Я считаю, что проблема objectalloc находится здесь. Может быть, мне просто нужны свежие глаза. Было бы здорово, если бы кто-то мог это понять. Извините, это довольно долго ... Я постараюсь и укорочу его.
@implementation UIImage(Blur)
- (UIImage *)blurredCopy:(int)pixelRadius
{
//VARS
unsigned char *srcData, *destData, *finalData;
CGContextRef context = NULL;
CGColorSpaceRef colorSpace;
void * bitmapData;
int bitmapByteCount;
int bitmapBytesPerRow;
//IMAGE SIZE
size_t pixelsWide = CGImageGetWidth(self.CGImage);
size_t pixelsHigh = CGImageGetHeight(self.CGImage);
bitmapBytesPerRow = (pixelsWide * 4);
bitmapByteCount = (bitmapBytesPerRow * pixelsHigh);
colorSpace = CGColorSpaceCreateDeviceRGB();
if (colorSpace == NULL) { return NULL; }
bitmapData = malloc(bitmapByteCount);
if (bitmapData == NULL) { CGColorSpaceRelease(colorSpace); }
context = CGBitmapContextCreate (bitmapData,
pixelsWide,
pixelsHigh,
8,
bitmapBytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedFirst);
if (context == NULL) { free (bitmapData); }
CGColorSpaceRelease(colorSpace);
free (bitmapData);
if (context == NULL) { return NULL; }
//PREPARE BLUR
size_t width = CGBitmapContextGetWidth(context);
size_t height = CGBitmapContextGetHeight(context);
size_t bpr = CGBitmapContextGetBytesPerRow(context);
size_t bpp = (CGBitmapContextGetBitsPerPixel(context)/8);
CGRect rect = {{0,0},{width,height}};
CGContextDrawImage(context, rect, self.CGImage);
// Now we can get a pointer to the image data associated with the bitmap
// context.
srcData = (unsigned char *)CGBitmapContextGetData (context);
if (srcData != NULL)
{
size_t dataSize = bpr * height;
finalData = malloc(dataSize);
destData = malloc(dataSize);
memcpy(finalData, srcData, dataSize);
memcpy(destData, srcData, dataSize);
int sums[5];
int i, x, y, k;
int gauss_sum=0;
int radius = pixelRadius * 2 + 1;
int *gauss_fact = malloc(radius * sizeof(int));
for (i = 0; i < pixelRadius; i++)
{
.....blah blah blah...
THIS IS JUST LONG CODE THE CREATES INT FIGURES
........blah blah blah......
}
if (gauss_fact) { free(gauss_fact); }
}
size_t bitmapByteCount2 = bpr * height;
//CREATE DATA PROVIDER
CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, srcData, bitmapByteCount2, NULL);
//CREATE IMAGE
CGImageRef cgImage = CGImageCreate(
width,
height,
CGBitmapContextGetBitsPerComponent(context),
CGBitmapContextGetBitsPerPixel(context),
CGBitmapContextGetBytesPerRow(context),
CGBitmapContextGetColorSpace(context),
CGBitmapContextGetBitmapInfo(context),
dataProvider,
NULL,
true,
kCGRenderingIntentDefault
);
//RELEASE INFORMATION
CGDataProviderRelease(dataProvider);
CGContextRelease(context);
if (destData) { free(destData); }
if (finalData) { free(finalData); }
if (srcData) { free(srcData); }
UIImage *retUIImage = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
return retUIImage;
}
Единственное, что я могу думать о том, что держится на objectalloc в этом UIImage * retUIImage = [UIImage imageWithCGImage: cgImage]; ... но как это сделать я выпускаю, что после того, как он был возвращен? Надеюсь, кто-то может помочь.
Я понятия не имею, если это связано с утечкой, но вы не должны называть 'свободный (BitmapData)', прежде чем выпустили контекст. Блоки памяти, выделенные с помощью 'malloc()', не имеют счетчиков сохранения, поэтому, если вы вызываете 'free()', он сразу освобождается, даже если CGContext использует его. – benzado
Вы ориентируетесь на iPhone OS 3.1 или выше? Это может быть ошибка в версии 3.0 или более ранней версии. Если вы используете 3.1, вам не нужно выделять битмапДата для 'CGBitmapContextCreate'. Также '_imageScaledToSize' является недокументированным звонком. Пожалуйста, не используйте его. Некоторые люди могут не захотеть ответить на ваш вопрос, если вы используете недокументированные звонки. – lucius
эй bbullis21 ваш код размытия работает нормально на устройстве ?? – Leena