【问题标题】:How to unload iPhone images to free up memory如何卸载 iPhone 图像以释放内存
【发布时间】:2011-06-01 14:24:12
【问题描述】:

我有一个 iPhone 游戏,它使用图像来显示诸如屏幕上的按钮之类的东西来控制游戏。图片不是很大,但我想“懒惰地”加载它们,并在不使用时从内存中卸载它们。

我有一个加载图像的函数,如下所示:

void loadImageRef(NSString *name, GLuint location, CGImageRef *textureImage)
{
    *textureImage = [UIImage imageNamed:name].CGImage;

    if (*textureImage == nil) {
        NSLog(@"Failed to load texture image");
        return;
    }

    NSInteger texWidth = CGImageGetWidth(*textureImage);
    NSInteger texHeight = CGImageGetHeight(*textureImage);

    GLubyte *textureData = (GLubyte *)malloc(texWidth * texHeight * 4);

    CGContextRef textureContext = CGBitmapContextCreate(textureData,
                                                        texWidth, texHeight,
                                                        8, texWidth * 4,
                                                        CGImageGetColorSpace(*textureImage),
                                                        kCGImageAlphaPremultipliedLast);

    CGContextTranslateCTM(textureContext, 0, texHeight);
    CGContextScaleCTM(textureContext, 1.0, -1.0);

    CGContextDrawImage(textureContext, CGRectMake(0.0, 0.0, (float)texWidth, (float)texHeight), *textureImage);
    CGContextRelease(textureContext);

    glBindTexture(GL_TEXTURE_2D, location);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);

    free(textureData);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}

我将CGImageRef 传递给函数的原因是为了以后可以释放它。但我不知道这样做是否正确?

我调用函数如下(例如):

loadImageRef(@"buttonConfig.png", textures[IMG_CONFIG], &imagesRef[IMG_CONFIG]);

当我完成它时,我按如下方式卸载它:

unloadImage(&imagesRef[IMG_CONFIG]);

调用函数:

void unloadImage(CGImageRef *image)
{
    CGImageRelease(*image);
}

但是当我运行该应用程序时,无论是卸载还是第二次加载(即再次需要它时),我都会收到 EXC_BAD_ACCESS 错误。我没有看到其他任何东西可以帮助确定问题的真正原因。

也许我从错误的角度解决了这个问题。图片懒加载的常用方法是什么,卸载图片释放内存的常用方法是什么?

非常感谢,

山姆

【问题讨论】:

    标签: iphone image memory-management cgimageref


    【解决方案1】:

    如果您想确保内容不会被缓存,您应该不惜一切代价避免使用 [UIImage imageNamed:name] 方法。 imageNamed 缓存它通过的所有图像。你想用

    UIImage *image = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:fileNameWithoutExtension ofType:fileNameExtension]];
    

    这样,您可以在使用完对象后简单地释放它并释放内存。

    Apple 已经使用 [UIImage imageNamed:] 改进了缓存,但它仍然不是按需提供的。

    【讨论】:

    • 感谢您的快速回复...我替换了以下代码,但现在根本没有加载图像,它们只是所有白色方块。知道我做错了什么吗? //*textureImage = [UIImage imageNamed:name].CGImage; UIImage *image = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%s", name] ofType:[NSString stringWithFormat:@"png"]]]; *textureImage = image.CGImage;我更改了传入的内容,以便不会在参数中传递文件扩展名。它始终是“png”。再次感谢您。
    • 抱歉,想通了...我将name 视为char*,而实际上它是NSString 对象。现在已正确加载。谢谢。
    猜你喜欢
    • 2021-07-20
    • 1970-01-01
    • 2011-05-05
    • 2010-12-06
    • 1970-01-01
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    • 2019-04-30
    相关资源
    最近更新 更多