OGeek|极客世界-中国程序员成长平台

标题: ios - 如何释放不再使用的 UIImages 的内存 [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-13 07:06
标题: ios - 如何释放不再使用的 UIImages 的内存

我正在尝试将一些较小的图像合并成一个较大的图像。应用程序因为内存不足而崩溃,但我不知道在使用后如何释放内存,所以它一直在累积直到应用程序崩溃。

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

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

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

+ (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) withImageWidthAGE_WIDTH withImageHeightAGE_HEIGHT];


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

ImageUtils 方法

+(UIImage *) addImageToImageUIImage *)sheet withImage2UIImage *)label andRectCGRect)cropRect withImageWidthint) width withImageHeightint) 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*)resizeImageUIImage*)image withWidthCGFloat)width withHeightCGFloat)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;
}



Best Answer-推荐答案


也许您的图像没有被解除分配,而是移动到 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 {} 将代码包装在循环中:

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) withImageWidthAGE_WIDTH withImageHeightAGE_HEIGHT];


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

关于ios - 如何释放不再使用的 UIImages 的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22584478/






欢迎光临 OGeek|极客世界-中国程序员成长平台 (http://sqlite.in/) Powered by Discuz! X3.4