开发者

How to unload iPhone images to free up memory

I have an iPhone game that uses images to display things such as buttons on screen to control the game. The images aren't huge, but I want to load them 开发者_StackOverflow中文版"lazily" and unload them from memory when they are not being used.

I have a function that loads images as follows:

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);
}

The reason I pass the CGImageRef to the function is so that I can free it later. But I don't know if this is the correct thing to do?

I call the function as follows (for example):

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

And when I'm finished with it I unload it as follows:

unloadImage(&imagesRef[IMG_CONFIG]);

which calls the function:

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

But when I run the app, I get EXC_BAD_ACCESS error, either when unloading, or loading for the second time (i.e. when it is needed again). I don't see anything else to help determine the real cause of the problem.

Perhaps I am attacking this issue from the wrong angle. What is the usual method of lazy loading of images, and what is the usual way to unload the image to free up the memory?

Many thanks in advance,

Sam


You should avoid using the [UIImage imageNamed:name] method at all costs if you want to ensure things don't stay cached. imageNamed caches all images it pulls through. You want to use

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

With that, you can simply release the object when you are done with it and free the memory.

Apple has improved caching with [UIImage imageNamed:] but it still isn't on demand.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜