1

我几乎可以肯定这段代码没有泄漏,但 Xcode 分析器报告说存在“潜在”泄漏(Xcode 4.6.1)。

+ (MySHA1hash *)sha1HashWithHashBytes:(unsigned char *)hash length:(unsigned int)length;
{
   return [[[MySHA1hash alloc] initWithHashBytes:hash length:length] autorelease];
}

XCode 分析器错误截图

如果问题是 Xcode 报告了误报,我想弄清楚如何以一种使警告静音的方式构造代码。

我也有可能以我不理解的方式泄漏,但如果有人能看到我实际上是如何泄漏的,我也会很高兴得到反馈。

这一定和我调用的init函数有关,因为如果我简单地将initWithHashBytes替换为init,那么泄漏就不再报告了。为此,我还包括了 initWithHashBytes 的主体。

- (id)initWithHashBytes:(unsigned char *)hash length:(unsigned int)length
{
    if (hash != nil && length <= SHA_DIGEST_LENGTH) {
        NSData *data = [NSData dataWithBytes:hash length:length];
        self = [self initWithHash:data];
    }
    else {
        self = nil;
    }
    return self;
}

- (id)initWithHash:(NSData *)hash
{
    if ([hash length] <= SHA_DIGEST_LENGTH && (self = [super init]) != nil) {
        finished = YES;
        [hash getBytes:sha_Result];
        hashValue = [NSNumber numberWithInt:[hash hash]];
    }
    else {
        self = nil;
    }
    return self;
}
4

3 回答 3

6

线

self = nil;

initWithHashBytes:(和initWithHash:)是问题。您正在分配一个对象,但如果您nil从 from返回initWithHashBytes:,该对象将被泄漏,因为您将调用autoreleasenil不是调用您分配的对象。

self在你回来之前释放nil,一切都应该很好。

于 2013-03-27T19:45:16.137 回答
3

在这种特殊情况下,显然存在需要修复的错误,但我有时看到需要抑制完全理解为无问题的警告(即报告的泄漏实际上不是泄漏)。

这是我期望在这里需要做的,但事实证明确实存在泄漏。所以我很高兴它得到了修复。我立即发现了另一个问题,这是一个明确无误的“误报”(我知道该错误被报告为“潜在泄漏”,所以实际上它不是误报,但这并不意味着我想看到每次我运行分析器时都在报告中)。

因此,我仍然有如何抑制这些警告的问题。事实证明,您可以轻松地将您希望分析器绕过的代码封装在 ifdef 检查 __clang_analyzer 中。

#ifndef __clang_analyzer__
  ... code you want to ignore ...
#endif

这里有一篇很好的文章。

于 2013-03-27T20:45:15.427 回答
1

你缺少一个[self release]before self = nil

您从中获取的对象alloc的引用计数为 +1,需要通过调用来平衡releaseor autorelease。对于从该类方法中返回实际对象的情况,该方法会处理所有事情sha1HashWithHashBytes:length:autorelease

对于您返回方法的情况,您nilinit方法是最后一个引用该分配对象的方法,因此它必须释放它。

于 2013-03-27T19:51:38.607 回答