画笔正确导致内存问题

时间:2010-10-18 07:40:40

标签: iphone

目前,由于大规模图像中的内存消耗,我使用的是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的

3 个答案:

答案 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];