1

私は、画像を使用して画面上のボタンなどを表示してゲームを制御する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);
}

しかし、アプリを実行すると、アンロード時または2回目のロード時(つまり、再度必要になったとき)にEXC_BAD_ACCESSエラーが発生します。問題の本当の原因を特定するのに役立つものは他にありません。

おそらく私はこの問題を間違った角度から攻撃しています。画像の遅延読み込みの通常の方法は何ですか?また、画像をアンロードしてメモリを解放する通常の方法は何ですか?

よろしくお願いします。

サム

4

1 に答える 1

1

物事がキャッシュされたままにならないようにする場合は、[UIImage imageNamed:name]メソッドの使用を絶対に避けてください。imageNamedは、プルスルーするすべての画像をキャッシュします。使いたい

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

これで、オブジェクトを使い終わったらオブジェクトを解放して、メモリを解放できます。

Appleは[UIImageimageNamed:]でキャッシュを改善しましたが、それでもオンデマンドではありません。

于 2011-06-01T15:10:06.517 に答える