我正在循环中从文档目录中读取图像。
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
并且应用程序崩溃。如果我用资源文件夹中的图像替换图像,应用程序不会崩溃。为什么这样?
答案 0 :(得分:2)
问题是您的按钮保持对全分辨率图像的引用。您需要做的是将图像缩小到按钮尺寸,并将缩小的图像设置为按钮背景。这样的事情可以解决问题:
在UIImage上创建一个类别......我们称之为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;
}
好的,现在回到你的代码。像其他海报一样,你需要一个自动释放池。
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
}
希望这能解决问题。
答案 1 :(得分:0)
将for
循环放在自动释放池中:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
for(...)
{
....
}
[pool release];
答案 2 :(得分:0)
使用NSAutoreleasePool。将代码保存在autoreleasepool中。
for(iArrCount=0;iArrCount<[arrImages count];iArrCount++)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
......
......
[pool drain];
}