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

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

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

分析器表明,在所有这些之后,创建并存储到临时编号中的 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);

静态分析器给出了一个干净的健康 list 。

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

最佳答案

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

您使用的是什么版本的 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。

关于objective-c - 为什么静态分析器显示此桥接 NSNumber 在 ARC 下泄漏?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7958048/

10-12 07:05