0

我刚刚遇到了 XCode 3.2 的 XCode 静态代码分析器的问题。它向我展示了一个潜在的泄漏,我认为这是不合理的。我只是想和其他人核实一下,确保它真的是误报。

这是主要代码(在某些函数体中):

NSError *error = nil;
NSData *urlData = /* ... */;
NSXMLDocument *doc = [[NSXMLDocument alloc] initWithData:urlData options:0 error:&error];
if (![self validateObject:doc withError:error]) {
    return;
}
// ...
[doc release];

这是上面调用的验证方法:

- (BOOL)validateObject:(id)object withError:(NSError *)error {
    if (!object) {
        // do something meaningful...
        return NO;
    } else {
        return YES;
    }
}

XCode 告诉我 doc 的分配是一个潜在的泄漏,因为 validate 方法可能返回 NO 并且 release 不会被发送到 doc。但事实上,如果初始化失败,initWithData:options: 会返回nil,并没有造成任何伤害。文档甚至说明了这一点。

那么,专家们是怎么说的呢?假阳性与否?

最好的,哈拉尔

4

3 回答 3

2

这不是误报,因为它在做正确的事情。但你是对的,在实践中,你实际上不会泄漏。[doc release]但是,您可以通过在过早返回之前放置 a 来使分析静音,或者autoreleaseNSXMLDocument方法结束时不显式释放它。

它不是误报的原因是分析器不会调查是什么validateObject:withError:。分析器的重点是单独分析每个方法,而不是对其调用的方法进行任何假设(除了标准的 Cocoa 命名,即new*, alloc/init*,copy*等 - 您在 ARC 中阅读的常见内容)。想象一下,你巧妙地改变了validateObject:withError:所做的事情。那么你最终可能会泄漏。它警告您更改代码以确保安全。

正如@JeremyP 所说(比我好得多):

“代码破坏了封装。你必须知道 -validateObject:withError: 的内部结构才能理解顶部的代码片段没有被破坏。”

于 2012-03-12T16:17:39.727 回答
1

静态分析器不够聪明,无法知道您的验证方法总是YES在对象不返回时返回nil。我也不会依赖它。将来您很可能会扩展验证方法的逻辑,因此即使不是的对象nil也不一定会通过验证。在这种情况下,您将引入泄漏。由于发送消息nil是无操作的,因此无论如何我都会释放(或自动释放)doc

于 2012-03-12T16:18:12.083 回答
1

Xcode 中的静态分析器无法识别这一点,因为它只能检测方法内的问题,而不是跨不同方法的问题。所以它不会在 validateObject 中查看它的作用。

如果您更改 validateObject 的实现,则可能会发生泄漏。您不应依赖 validateObject 的实现。

您应该通过自动释放 NSXMLDocument 来修复这种潜在的泄漏。

NSXMLDocument *doc = [[[NSXMLDocument alloc] initWithData:urlData options:0 error:&error] autorelease];
于 2012-03-12T16:16:19.993 回答