我有一款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错误。我没有看到任何其他东西来帮助确定问题的真正原因。
也许我从错误的角度攻击这个问题。什么是延迟加载图像的常用方法,以及卸载图像以释放内存的常用方法是什么?
非常感谢,
萨姆
答案 0 :(得分:1)
如果要确保不缓存内容,则应该不惜一切代价避免使用[UIImage imageNamed:name]方法。 imageNamed缓存它所经过的所有图像。你想用
UIImage *image = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:fileNameWithoutExtension ofType:fileNameExtension]];
有了它,您可以在完成后释放该对象并释放内存。
Apple使用[UIImage imageNamed:]改进了缓存,但仍然没有按需提供。