目前,由于大规模图像中的内存消耗,我使用的是UIView而不是UIImageview。以下是我正在使用的相同代码。
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, rect);
[myImage drawInRect:rect];
}
-(void) SetImage:(UIImage*) aImage
{
if(!aImage)
return;
if(myImage)
{
[myImage release];
myImage = nil;
}
myImage = [[[UIImage alloc]initWithCGImage:aImage.CGImage] retain];
[self setNeedsDisplay];
}
每次更新时都会导致内存泄漏8 MB(使用Instrument检查),并再次设置相同的图像。如果我评论
[self setNeedsDisplay];
没有泄漏。如果我做错了什么,任何人都可以帮助我或者任何人都可以帮助我使用子类UIImageview处理大比例图像。
// Calling functions
-(void) FitToCardStart
{
UIImage* temp = ScaleImage([iImageBgView GetImage]);
[iImageBgView SetImage:temp];
[temp release];
temp = nil;
}
// ScaleImage
UIImage* ScaleImage(UIImage* image)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
int kMaxResolution = 1800;
CGImageRef imgRef = image.CGImage;
CGFloat width = CGImageGetWidth(imgRef);
CGFloat height = CGImageGetHeight(imgRef);
CGAffineTransform transform = CGAffineTransformIdentity;
CGRect bounds = CGRectMake(0, 0, width, height);
if (width < kMaxResolution || height < kMaxResolution)
{
CGFloat ratio = width/height;
if (ratio > 1)
{
bounds.size.width = kMaxResolution;
bounds.size.height = bounds.size.width / ratio;
}
else
{
bounds.size.height = kMaxResolution;
bounds.size.width = bounds.size.height * ratio;
}
}
CGFloat scaleRatio = bounds.size.width / width;
CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
UIImageOrientation orient = image.imageOrientation;
switch(orient)
{
case UIImageOrientationUp: //default
transform = CGAffineTransformIdentity;
break;
default:
[NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];
}
UIGraphicsBeginImageContext(bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextScaleCTM(context, scaleRatio, -scaleRatio);
CGContextTranslateCTM(context, 0, -height);
CGContextConcatCTM(context, transform);
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
UIImage* temp = [[[UIImage alloc] initWithCGImage:imageCopy.CGImage] retain];
CGImageRelease(imgRef);
CGContextRelease(context);
[pool release];
return temp;
}
谢谢,
Sagar的
答案 0 :(得分:1)
myImage = [[[UIImage alloc]initWithCGImage:aImage.CGImage] retain];
这一行有冗余保留 - 因为你正在分配新的UIIMage对象(使用+ alloc)方法,所以你不需要额外保留它。
编辑:ScaleImage方法与冗余保留具有相同的问题:
// remove extra retain here
UIImage* temp = [[[UIImage alloc] initWithCGImage:imageCopy.CGImage] retain];
// should be
UIImage* temp = [[UIImage alloc] initWithCGImage:imageCopy.CGImage];
代码样式注释 - 最好在方法名称中指明返回对象所需的内存管理行为 - 因为方法返回的图像需要释放,方法名称应包含“new”,“alloc”中的内容“,”复制“,”创造“......
答案 1 :(得分:1)
你的问题就在这一行:
myImage = [[[UIImage alloc]initWithCGImage:aImage.CGImage] retain];
alloc
已经为您提供了1的保留计数,而额外的retain
最终保留计数为2,这太高了。删除retain
,一切都会好的。
答案 2 :(得分:0)
我建议不要创建新图像,而只是保留aImage实例。
myImage = [aImage retain];
我绝对必须把它变成一个新的实例,你是以非常迂回的方式做到的。 复制将是一个更好的选择。
myImage = [aImage copy];