如何释放不再使用的UIImages内存

时间:2014-03-22 22:28:28

标签: ios objective-c memory-management uiimage

我正在尝试将一些较小的图像合并为一个较大的图像。该应用程序崩溃是因为内存耗尽,但我无法弄清楚如何在使用后释放内存,因此它会一直存在,直到应用程序崩溃。

addImageToImage和resizeImage例程似乎导致崩溃,因为在不再需要它之后我无法释放内存。我在这个项目中使用自动引用计数。我已经尝试将图像设置为nil,但这并不能阻止崩溃。

testImages位于从主ViewController调用的一个类中,而addImageToImage和resizeImage位于另一个名为ImageUtils的类中。

有人可以查看此代码并向我解释如何正确释放这两个例程分配的内存。我不能在图像上调用release,因为项目使用ARC并将它们设置为nil没有效果。

+ (void)testImages
    {
    const int IMAGE_WIDTH = 394;
    const int IMAGE_HEIGHT = 150;
    const int PAGE_WIDTH = 1275;
    const int PAGE_HEIGHT = 1650;
    const int COLUMN_WIDTH = 30;
    const int ROW_OFFSET = 75;

    CGSize imageSize = CGSizeMake(PAGE_WIDTH, PAGE_HEIGHT);
    UIGraphicsBeginImageContextWithOptions(imageSize, YES, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextFillRect(context, CGRectMake(0, 0, imageSize.width, imageSize.height));
    UIImage *psheet = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    CGSize collageSize = CGSizeMake(IMAGE_WIDTH, IMAGE_HEIGHT);
    UIGraphicsBeginImageContextWithOptions(collageSize, YES, 0);
    CGContextRef pcontext = UIGraphicsGetCurrentContext();
    CGContextFillRect(pcontext, CGRectMake(0, 0, collageSize.width, collageSize.height));
    UIImage *collage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();


    float row = 1;
    float column = 1;
    int index = 1;
    int group = 1;
    for (int i = 0; i < 64; i++)
    {
        NSLog(@"processing group %i - file %i ", group, index++);

        psheet = [ImageUtils  addImageToImage:psheet withImage2:collage andRect:CGRectMake((IMAGE_WIDTH*(column-1)) + (COLUMN_WIDTH * column), (IMAGE_HEIGHT * (row-1)) + ROW_OFFSET, IMAGE_WIDTH, IMAGE_HEIGHT) withImageWidth:PAGE_WIDTH withImageHeight:PAGE_HEIGHT];


        column++;
        if (column > 3) {
            column = 1;
            row++;
        }
        if (index == 15)
        {
            group++;
            index = 1;
            row = 1;
            column = 1;
            UIImage *editedImage = [ImageUtils resizeImage:psheet withWidth:PAGE_WIDTH * 2 withHeight:PAGE_HEIGHT * 2];
            editedImage = nil;
        }
    }
}

ImageUtils方法

+(UIImage *) addImageToImage:(UIImage *)sheet withImage2:(UIImage *)label andRect:(CGRect)cropRect withImageWidth:(int) width withImageHeight:(int) height
{

    CGSize size = CGSizeMake(width,height);

    UIGraphicsBeginImageContext(size);

    CGPoint pointImg1 = CGPointMake(0,0);
    [sheet drawAtPoint:pointImg1];

    CGPoint pointImg2 = cropRect.origin;
    [label drawAtPoint: pointImg2];

    UIImage* result = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return result;

}

+ (UIImage*)resizeImage:(UIImage*)image withWidth:(CGFloat)width withHeight:(CGFloat)height
{
    CGSize newSize = CGSizeMake(width, height);
    CGFloat widthRatio = newSize.width/image.size.width;
    CGFloat heightRatio = newSize.height/image.size.height;

    if(widthRatio > heightRatio)
    {
        newSize=CGSizeMake(image.size.width*heightRatio,image.size.height*heightRatio);
    }
    else
    {
        newSize=CGSizeMake(image.size.width*widthRatio,image.size.height*widthRatio);
    }


    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
    [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

1 个答案:

答案 0 :(得分:4)

也许您的图片未被取消分配,但已移至autorelease pool

  

许多程序会创建自动释放的临时对象。这些   对象添加到程序的内存占用,直到结束   块。在许多情况下,允许临时对象累积   直到当前事件循环迭代结束才导致   过度开销;但是,在某些情况下,您可以创建一个   大量临时对象大量增加内存   足迹和你想要更快地处置。在这些   在后一种情况下,您可以创建自己的自动释放池块。在   块的结尾,临时对象被释放,这通常是   导致他们的释放,从而减少程序的内存   足迹

尝试使用@autoreleasepool {}

将代码包装在循环中
for (int i = 0; i < 64; i++)
{
@autoreleasepool {
    NSLog(@"processing group %i - file %i ", group, index++);

    psheet = [ImageUtils  addImageToImage:psheet withImage2:collage andRect:CGRectMake((IMAGE_WIDTH*(column-1)) + (COLUMN_WIDTH * column), (IMAGE_HEIGHT * (row-1)) + ROW_OFFSET, IMAGE_WIDTH, IMAGE_HEIGHT) withImageWidth:PAGE_WIDTH withImageHeight:PAGE_HEIGHT];


    column++;
    if (column > 3) {
        column = 1;
        row++;
    }
    if (index == 15)
    {
        group++;
        index = 1;
        row = 1;
        column = 1;
        UIImage *editedImage = [ImageUtils resizeImage:psheet withWidth:PAGE_WIDTH * 2 withHeight:PAGE_HEIGHT * 2];
        editedImage = nil;
    }
}
}