我刚遇到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:并且不会造成任何损害。文档甚至陈述了这一点。
那么,专家们说什么呢?是假的还是没有?
最好,哈拉尔德
答案 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
。