声称对象的分析器在没有被释放时被释放

时间:2012-08-18 12:49:25

标签: objective-c ios xcode memory-management objective-c++

我在这段代码中遇到静态分析错误,这对我没有任何意义。错误是:

  

引用计数对象在发布后使​​用

这是胶水代码,允许在最初用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],它不应该存在,我在发现此警告时删除了该{{1}}。然而,即使在完全清理和重建之后,我仍然会收到警告。我做错了什么吗? Xcode中的Clean命令无法正确清理某些内容吗?

2 个答案:

答案 0 :(得分:2)

分析仪可能是正确的,至少在一般方面。

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

通常,“init”实际上可能会丢弃传入的对象并返回不同的对象。是否属于“Texture2D”的情况我不知道,但如果分析仪是针对一般情况那么它是正确的。

您应该可以使用

解决这个问题
Texture2D *loadedTex = [Texture2D alloc];
loadedTex=[loadedTex initWithImage:image format:format];

或者简单地组合两个调用,就像在大多数Objective-C示例中一样。

答案 1 :(得分:0)

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

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

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

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