如何释放不再使用的UIImages的内存 [英] How can I release memory of UIImages no longer used

查看:70
本文介绍了如何释放不再使用的UIImages的内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将许多较小的图像合并为较大的图像.该应用程序崩溃是因为它的内存不足,但是我无法弄清楚在使用完内存后如何释放它,因此它会一直累积到应用程序崩溃为止.

I am attempting to merge a number of smaller images into a larger one. The app crashes because it runs out of memory, but I cannot figure out how to release the memory after it is used, so it keeps building up til the app crashes.

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

The addImageToImage and resizeImage routines appears to be causing the crash since I cannot free up their memory after it is no longer needed. I am using Automatic Reference Counting in this project. I have tried setting the image to nil but that does not stop the crashing.

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

testImages is in one class that is called from the main ViewController, while addImageToImage and resizeImage are in another class called ImageUtils.

有人可以看一下这段代码并向我解释如何正确释放这两个例程分配的内存.我无法在图像上调用release,因为该项目使用ARC,并且将它们设置为nil无效.

Can someone look at this code and explain to me how to properly release the memory allocated by these two routines. I cannot call release on the images since the project uses ARC and setting them to nil has no effect.

+ (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方法

ImageUtils methods

+(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;
}

推荐答案

也许您的图像未释放,但已移至

Maybe your images are not deallocated but moved to autorelease pool.

许多程序会创建自动释放的临时对象.这些 对象会增加程序的内存占用量,直到 堵塞.在许多情况下,允许临时物体堆积 直到当前事件循环迭代的结束不会导致 过多的开销;但是,在某些情况下,您可以创建一个 大量大量添加到内存中的临时对象 足迹,并且您希望更快地处理.在这些 对于后一种情况,您可以创建自己的自动释放池块.在 块的末尾,临时对象被释放,通常 导致它们的重新分配,从而减少了程序的内存 足迹

Many programs create temporary objects that are autoreleased. These objects add to the program’s memory footprint until the end of the block. In many situations, allowing temporary objects to accumulate until the end of the current event-loop iteration does not result in excessive overhead; in some situations, however, you may create a large number of temporary objects that add substantially to memory footprint and that you want to dispose of more quickly. In these latter cases, you can create your own autorelease pool block. At the end of the block, the temporary objects are released, which typically results in their deallocation thereby reducing the program’s memory footprint

尝试使用@autoreleasepool {}将代码包装在循环内:

Try to wrap code inside the loop with @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;
    }
}
}

这篇关于如何释放不再使用的UIImages的内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆