4

当针对我已转换为使用 ARC 的代码运行 Clang 静态分析器时,它报告此代码块中的 NSNumber 为泄漏:

NSNumber *temporaryNumber = [NSNumber numberWithFloat:0.85];
CFNumberRef compressionQuality = CFBridgingRetain(temporaryNumber);

CFDictionarySetValue(snapshotMetaAndOpts, kCGImageDestinationLossyCompressionQuality, compressionQuality);
CFRelease(compressionQuality);

分析器表明创建并存储到temporaryNumber 中的NSNumber 在所有这些之后以+1 保留计数结束,因此泄漏。我知道我可以很容易地做到

CFDictionarySetValue(snapshotMetaAndOpts, kCGImageDestinationLossyCompressionQuality, (__bridge CFNumberRef)[NSNumber numberWithFloat:0.85]);

但我仍在尝试了解 ARC 中桥接的确切操作,所以我试图解开上述问题。实际分析仪输出如下:

静态分析仪结果的可视化描述

我阅读的方式CFBridgingRetain()__bridge_retained,他们通过将保留计数增加 1 来将 ARC 管理的 NSObject 的所有权转移给 Core Foundation。我将其与相应的CFRelease(). 我希望 NSNumber 被创建为一个自动释放的对象,因此在 ARC 端完全平衡。

同样,如果我使用普通__bridge演员执行以下操作:

NSNumber *temporaryNumber = [NSNumber numberWithFloat:0.85];
CFNumberRef compressionQuality = (__bridge CFNumberRef)temporaryNumber;
CFDictionarySetValue(snapshotMetaAndOpts, kCGImageDestinationLossyCompressionQuality, compressionQuality);
CFRelease(compressionQuality);

静态分析器给了它一个干净的健康账单。

我是否误读了对象免费桥接的方式,或者这是静态分析器中的错误?

4

1 回答 1

5

编辑: 这是一个分析器错误。我的机器上有最新版本的独立分析器,没有警告。我使用当前的运输分析器对构建进行了验证,并得到了与您相同的结果。看起来它已经很好了。

你使用的是什么版本的 Xcode?我刚刚测试了以下内容。

int main(int argc, char *argv[])
{
    @autoreleasepool 
    {
        CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

        NSNumber *temporaryNumber = [NSNumber numberWithFloat:0.85];
        CFNumberRef compressionQuality = CFBridgingRetain(temporaryNumber);

        CFDictionarySetValue(dict, CFSTR("Test"), compressionQuality);
        CFRelease(compressionQuality);

        CFRelease(dict);
    }
}

这按预期工作并且不提供分析器警告。这是 10.7 上的最新 4.2,使用 iOS SDK。

于 2011-10-31T18:40:08.553 回答