【问题标题】:Build and Analyze false positive on leak detection?建立和分析泄漏检测的误报?
【发布时间】:2011-12-08 21:55:53
【问题描述】:

我有这个代码:

- (CGImageRef)createImageWithContext:(CGContextRef)context
{
    return CGBitmapContextCreateImage(context);
}

- (void)fooWithContext:(CGContextRef)context
{
    CGImageRef imgRef = [self createImageWithContext:context];
    CGImageRelease(imgRef);
}

这是一个在 Xcode 中构建并启用 ARC 的 Objective-C 项目。 Build and Analyze 报告了两个错误:一个在 CGBitmapContextCreateImage 行上识别潜在泄漏,另一个在 CGImageRelease 上,指出“调用者此时不拥有的对象的引用计数不正确递减”。

如果我将这两个功能合二为一:

- (void)fooWithContext:(CGContextRef)context
{
    CGImageRef imgRef = CGBitmapContextCreateImage(context);
    CGImageRelease(imgRef);
}

我没有收到任何警告。

静态代码分析错误?还是我在这里遗漏了什么?

【问题讨论】:

    标签: objective-c automatic-ref-counting


    【解决方案1】:

    按照标准 Cocoa 命名约定,以单词 create 开头的方法应该返回一个非拥有引用。您正在返回一个保留对象,但您应该返回一个非保留对象。因此,当分析器查看-createImageWithContext: 时,它发现它应该返回一个非保留对象,但实际上返回的是一个保留对象。因此是第一个警告。

    -fooWithContext: 中,它会查看您的代码并说“嘿,根据我的命名约定,createImageWithContext: 应该返回一个非拥有引用。但随后他们发布了一些他们不拥有的东西!这很糟糕!”因此是第二个警告。

    您可以通过将-createImageWithContext: 的名称更改为以new 开头的名称来解决此问题,例如-newImageWithContext:。或者,您可以使用 cf_returns_retained macro 注释该方法,以向静态分析器表明该方法正在返回一个拥有引用。

    【讨论】:

    • 啊,我想我明白了我的困惑——核心基础功能使用不同的规则。所以 CGCreate 在所有权规则方面等同于 -new*。谢谢。
    • 考虑到 CGCreate 函数返回拥有的引用的(旧的?)约定,这对我来说似乎很奇怪和倒退。当包含“Create”的函数具有完全相反的语义时,Apple 选择让以“create”开头的方法成为非拥有引用是否有充分的理由?我真的对此感到困惑。
    • shrug 也许出于同样的原因,以allocinit 开头的CF 函数不返回拥有引用。它们是独立的框架,独立的语言,,并且有独立的规则。就是这样。
    【解决方案2】:

    我想这是一个“误报”,这真的很有意义:

    分析器不知道createImageWithContext: 中的返回值一定会被释放(您可以在其他地方调用createImageWithContext:,之后您不执行CGImageRelease),也不知道@ fooWithContext: 中的 987654324@ 已正确保留。

    我的 2 美分 :)

    【讨论】:

      猜你喜欢
      • 2011-02-08
      • 1970-01-01
      • 1970-01-01
      • 2010-11-24
      • 1970-01-01
      • 2010-10-31
      • 2015-08-21
      • 2023-03-19
      • 1970-01-01
      相关资源
      最近更新 更多