建立并分析漏检误报



我有这样的代码:

- (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行上,识别潜在的泄漏,另一个在cgimagerrelease上,注意到"不正确地减少了调用者此时不拥有的对象的引用计数"。

如果我将这两个函数合并为一个:

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

我没有收到任何警告。

静态代码分析bug?还是我遗漏了什么?

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

-fooWithContext:中,它查看您的代码并说"嘿,根据我的命名约定,createImageWithContext:应该返回一个非拥有的引用。但他们释放了不属于他们的东西!那就糟糕了!"因此出现了第二个警告。

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

我想这是一个"假阳性",这真的很有意义:

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

我的2美分

最新更新