Được rồi, tôi đang gặp khó khăn trong việc theo dõi sự rò rỉ bộ nhớ này. Khi chạy kịch bản này tôi không thấy bất kỳ rò rỉ bộ nhớ nào, nhưng đối tượng của tôi đang leo lên. Các công cụ trỏ tới CGBitmapContextCreateImage> create_bitmap_data_provider> malloc, điều này chiếm 60% đối tượng của tôi.iPhone - UIImage Leak, CGBitmapContextCreateImage Leak
Mã này được gọi nhiều lần bằng 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];
Dưới đây là chức năng làm mờ. Tôi tin rằng vấn đề objectalloc nằm ở đây. Có lẽ tôi chỉ cần một đôi mắt mới. Sẽ là tuyệt vời nếu ai đó có thể hình dung ra điều này. Xin lỗi nó là loại dài ... Tôi sẽ cố gắng và rút ngắn nó.
@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;
}
Điều duy nhất tôi có thể nghĩ rằng đang nắm giữ lên objectalloc được UIImage này * retUIImage = [UIImage imageWithCGImage: cgImage]; ... nhưng làm thế nào để làm tôi phát hành sau khi nó đã được trả lại? Hy vọng rằng ai đó có thể giúp đỡ.
Tôi không biết liệu nó có liên quan đến rò rỉ hay không, nhưng bạn không nên gọi 'free (bitmapData)' trước khi bạn phát hành ngữ cảnh. Các khối bộ nhớ được cấp phát bằng 'malloc()' không có các bộ đếm lưu giữ, vì vậy nếu bạn gọi 'free()' nó được giải phóng ngay lập tức, ngay cả khi CGContext đang sử dụng nó. – benzado
Bạn đang nhắm mục tiêu hệ điều hành iPhone 3.1 trở lên? Nó có thể là một lỗi trong khuôn khổ 3.0 hoặc trước đó. Nếu bạn đang sử dụng 3.1, bạn không cần phân bổ bitmapData cho 'CGBitmapContextCreate'. Ngoài ra '_imageScaledToSize' là cuộc gọi không có giấy tờ. Xin vui lòng không sử dụng nó. Một số người có thể không sẵn lòng trả lời câu hỏi của bạn nếu bạn đang sử dụng các cuộc gọi không có giấy tờ. – lucius
hey bbullis21 mã mờ của bạn có hoạt động tốt trên thiết bị không ?? – Leena