2011-06-01 27 views
1

我有一款iPhone遊戲,使用圖像來顯示諸如屏幕上的按鈕來控制遊戲。這些圖像並不是很大,但我希望「懶洋洋地」加載它們,並在不使用它們時將它們從內存中卸載。如何卸載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錯誤,無論是卸載時,或第二次加載(即當它再次需要時)。我沒有看到其他任何東西來幫助確定問題的真正原因。

也許我從錯誤的角度來攻擊這個問題。什麼是延遲加載圖像的常用方法,以及卸載圖像以釋放內存的常用方法是什麼?

提前許多感謝,

山姆

回答

1

應避免使用[UIImage的imageNamed:名字]的方法,不惜一切代價,如果你想確保事情不留緩存。 imageNamed緩存所有圖像。你想使用

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

因此,你可以簡單地釋放對象,當你完成它並釋放內存。

蘋果改進了與[UIImage imageNamed:]緩存,但它仍然不是按需。

+0

感謝您的快速回復......我替換了下面的代碼,但現在圖像根本沒有加載,它們只是所有的白色方塊。任何想法我做錯了什麼? \t \t // * textureImage = [UIImage imageNamed:name] .CGImage; \t UIImage * image = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@「%s」,name] ofType:[NSString stringWithFormat:@「png」]]]; \t \t * textureImage = image.CGImage; \t 我改變了傳入的內容,以便文件擴展名不會傳入參數中。它總是「png」。再次感謝你。 – Sam 2011-06-02 01:32:07

+0

對不起,算了一下......當我把'name'當作'char *'的時候,它實際上是'NSString'對象。它現在正確加載。謝謝。 – Sam 2011-06-02 12:26:08

+0

很高興工作! – Smith3 2011-06-02 13:53:13