在XCode 3.2中静态分析代码时出现误报

时间:2012-03-12 15:59:30

标签: objective-c static-code-analysis false-positive

我刚遇到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并且不会将发布发送到doc。但事实上,如果初始化失败,则由initWithData:options返回nil:并且不会造成任何损害。文档甚至陈述了这一点。

那么,专家们说什么呢?是假的还是没有?

最好,哈拉尔德

3 个答案:

答案 0 :(得分:2)

这不是误报,因为它正在做正确的事。但你是对的,在实践中,你实际上并没有泄漏。但是,您可以通过在提前返回之前放置[doc release]autorelease NSXMLDocument并在方法结束时不明确释放它来使分析静音。

它不是误报的原因是分析仪不会查看validateObject:withError:的作用。分析器的要点是分别分析每个方法,而不是假设它调用的方法(除了标准的Cocoa命名,即new*alloc/init*copy*等 - 通常你用ARC读到的东西)。想象一下,你巧妙地改变了validateObject:withError:所做的事情。然后你最终可能会泄漏。它会警告您更改代码以确保安全。

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

  

"代码打破了封装。你必须知道内部的   -validateObject:withError:了解顶部代码段没有被破坏。"

答案 1 :(得分:1)

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

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

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

NSXMLDocument *doc = [[[NSXMLDocument alloc] initWithData:urlData options:0 error:&error] autorelease];

答案 2 :(得分:1)

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