从文档目录读取图像时发生内存泄漏 [英] Memory leak on reading images from document directory
问题描述
我正在循环读取文档目录中的图像.
I am reading images from document directory in a loop.
for(iArrCount=0;iArrCount<[arrImages count];iArrCount++)
{
UIButton *btnImage = [UIButton buttonWithType:UIButtonTypeCustom];
btnImage.frame = CGRectMake(xRow, yRow, width, height);
[btnImage addTarget:self action:@selector(imageDetails:) forControlEvents:UIControlEventTouchUpInside];
btnImage.tag = iCount;
if(iCount<[arrImages count])
{
NSString *workSpacePath=[[self applicationDocumentsDirectory] stringByAppendingPathComponent:[arrImages objectAtIndex:iCount]];
[btnImage setBackgroundImage:[UIImage imageWithData:[NSData dataWithContentsOfFile:workSpacePath]] forState:UIControlStateNormal];
[scrollImages addSubview:btnImage];
}
}
这样做时,控制权转到了 didRecieveMemoryWarning
,应用程序崩溃了.如果我用资源文件夹中的图像替换该图像,则应用程序不会崩溃.为什么这样?
On doing so, control goes to didRecieveMemoryWarning
and application crashes. If I replace the image by a image from resource folder, application does not crashes. Why so?
推荐答案
问题是您的按钮正在维护对全分辨率图像的引用.您需要做的是按比例缩小图像到按钮尺寸,并将按比例缩小的图像设置为按钮背景.这样的事情应该可以解决问题:
The problem is that your buttons are maintaining a reference to the full resolution image. What you will need to do is scale down the image to your button dimensions and set that scaled down image as your button background. Something like this should do the trick:
在UIImage上创建一个类别...我们将其命名为UIImage + Scaler.h
Create a category on UIImage... Let's call it UIImage+Scaler.h
// UIImage+Scaler.h
#import <UIKit/UIKit.h>
@interface UIImage (Scaler)
- (UIImage*)scaleToSize:(CGSize)size;
@end
执行:
// UIImage+Scaler.m
#import "UIImage+Scaler.h"
#define kBitsPerComponent 8
#define kBitmapInfo kCGImageAlphaPremultipliedLast
- (UIImage*)scaleToSize:(CGSize)size
{
CGBitmapInfo bitmapInfo = kBitmapInfo;
size_t bytesPerRow = size.width * 4.0;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, size.width,
size.height, kBitsPerComponent,
bytesPerRow, colorSpace, bitmapInfo);
CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
CGContextDrawImage(context, rect, self.CGImage);
CGImageRef scaledImageRef = CGBitmapContextCreateImage(context);
UIImage* scaledImage = [UIImage imageWithCGImage:scaledImageRef];
CGImageRelease(scaledImageRef);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
return scaledImage;
}
确定,现在返回您的代码.就像其他海报所说的那样,您需要一个自动释放池.
OK, now back to your code. Like the other posters said you'll need an autorelease pool.
CGSize buttonSize = CGSizeMake(width, height);
for(iArrCount=0;iArrCount<[arrImages count];iArrCount++)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
UIButton *btnImage = [UIButton buttonWithType:UIButtonTypeCustom];
btnImage.frame = CGRectMake(xRow, yRow, width, height);
[btnImage addTarget:self
action:@selector(imageDetails:)
forControlEvents:UIControlEventTouchUpInside];
btnImage.tag = iCount;
if(iCount<[arrImages count])
{
NSString *workSpacePath=[[self applicationDocumentsDirectory]
stringByAppendingPathComponent:
[arrImages objectAtIndex:iCount]];
UIImage* bigImage = [UIImage imageWithData:[NSData
dataWithContentsOfFile:workSpacePath]];
UIImage* smallImage = [bigImage scaleToSize:buttonSize];
[btnImage setBackgroundImage:smallImage forState:UIControlStateNormal];
[scrollImages addSubview:btnImage];
}
[pool drain]; // must drain pool inside loop to release bigImage
}
希望这可以解决问题.
这篇关于从文档目录读取图像时发生内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!