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 示例中所做的那样。

于 2012-08-18T13:04:36.397 回答
0

在这种情况下,您应该始终在创建对象时结合allocand调用initXXX

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

init 方法不需要返回与调用它的对象相同的对象,它可以返回不同的对象。

在这种情况下,您的结果loadedTex = [Texture2D alloc]将被释放并initWithImage返回一个不同的对象(您丢弃)。

于 2012-08-18T13:02:03.573 回答