0

このコードで静的分析エラーが発生しましたが、これは私には意味がありません。エラーは次のとおりです。

参照カウントされたオブジェクトは、リリース後に使用されます

これは、元々C++で記述されたゲームでPNGをロードできるようにするグルーコードです。

int pngLoad(const char *filename, pngInfo *info, int format, GLuint *textureName)
{
    char fullPath[Engine::Settings::MaxPath];
    strcpy(fullPath, filename);
    appendAppBundlePath(fullPath);

    NSString *path = [NSString stringWithCString:fullPath encoding:NSUTF8StringEncoding];
    NSData *data = [[NSData alloc] initWithContentsOfFile:path];
    UIImage *image = [[UIImage alloc] initWithData:data];
    [data release];

    Texture2D *loadedTex = [Texture2D alloc];

    // ##### Analyzer claims the object is released here: #####
    [loadedTex initWithImage:image format:format];

    int didLoad;

    // ##### Error is here: #####
    if (loadedTex.contentSize.width == 0 || loadedTex.contentSize.height == 0)
    {
        didLoad = 0;
    }
    else
    {
        didLoad = 1;

        *textureName = loadedTex.name;

        // return texture info
        info->ScaleFactor = loadedTex.scaleFactor;
        info->Width = (float)image.size.width / (float)info->ScaleFactor;
        info->Height = (float)image.size.height / (float)info->ScaleFactor;
        info->Alpha = 1;
        info->PaddedWidth = loadedTex.pixelsWide;
        info->PaddedHeight = loadedTex.pixelsHigh;
    }

    [loadedTex release];
    [image release];

    return didLoad;
}

この警告を使用するTexture2D *loadedTex = [[Texture2D alloc] retain];と削除されますが、オブジェクトがリークしたという警告が表示されるため、ここで何かが非常に奇妙になります。

initWithImage:format:以前はそこにあるべきではなかったものが含まれて[self release]いましたが、この警告を見つけたときに削除しました。ただし、完全にクリーンアップして再構築した後でも、警告が表示されます。私は何か他のことを間違っていますか?XcodeのCleanコマンドで何かが適切にクリーンアップされていませんか?

4

2 に答える 2

2

アナライザーは、少なくとも一般的な方法では正しいかもしれません。

Texture2D *loadedTex = [Texture2D alloc];
[loadedTex initWithImage:image format:format];

一般に、「init」は実際に渡されたオブジェクトを破棄し、別のオブジェクトを返す場合があります。これが「Texture2D」の場合であるかどうかは私にはわかりませんが、アナライザーが一般的な場合に当てはまる場合は正しいです。

を使用してそれを回避できるはずです

Texture2D *loadedTex = [Texture2D alloc];
loadedTex=[loadedTex initWithImage:image format:format];

または、ほとんどのObjective-Cの例で行われているように、2つの呼び出しを単純に組み合わせることによって。

于 2012-08-18T13:04:36.397 に答える
0

この場合、オブジェクトを作成するときは常にallocと呼び出しを組み合わせる必要がありますinitXXX

Texture2D *loadedTex = [[Texture2D alloc] initWithImage:image format:format];

initメソッドは、呼び出されたときと同じオブジェクトを返す必要はありません。別のオブジェクトを返すことができます。

この場合、からの結果loadedTex = [Texture2D alloc]が解放されinitWithImage、別のオブジェクト(破棄したもの)が返されます。

于 2012-08-18T13:02:03.573 に答える