• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

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

[复制链接]
菜鸟教程小白 发表于 2022-12-13 07:06:47 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

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

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/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap