0

我开始使用静态代码分析来查找代码中的内存管理问题。我发现它非常有用,但是我编写的一些代码肯定不会导致内存泄漏(仪器不报告任何内容),但分析器正在报告。我认为这是我以不友好的方式编写代码的问题。这是一个例子

for (glyphUnit *ellipsisDot in ellipsisArray) {
    CGPathRef newDot = CGPathCreateCopyByTransformingPath(ellipsisDot.glyphPath, &ellipsisTransform);
    CGPathRelease(ellipsisDot.glyphPath);  // Incorrect decrement of the reference count of an object that is not owned at this point by the caller
    ellipsisDot.glyphPath = newDot;
}        

whereglyphUnit是一个简单的自定义类,它具有 aGCPathRef作为属性,自定义类在其dealloc方法中释放它。所以在这个循环中,我正在转换路径并将其存储在一个newDot然后释放原始 glyphPath 以便我可以将新创建​​的一个分配给它。我可以看到这是如何让代码分析器感到困惑,它给出了一条消息,我正在递减一个我不拥有的对象。是否有另一种方法可以在不混淆新路径的情况下进行交换?

4

2 回答 2

3

它应该是,

for (glyphUnit *ellipsisDot in ellipsisArray) {
    CGPathRef newDot = CGPathCreateCopyByTransformingPath(ellipsisDot.glyphPath, &ellipsisTransform);
    ellipsisDot.glyphPath = newDot;
    CGPathRelease(newDot); 
} 

您是newDot通过执行 CG CreateCopy 操作来创建的,并且您需要对该变量进行释放。所以分析器警告你没有ellipsisDot.glyphPath释放它的参数。您试图在这里释放错误的参数。当您将该发布声明放在第二行时,ellipsisDot.glyphPath并且newDot指向两个单独的实例。仅在第三行,您分配newDotellipsisDot.glyphPath.

于 2013-01-17T22:42:27.283 回答
0

事实证明,我忘记了在我的自定义glyphUnit类中定义 setter。在对象的 ARC 世界中并习惯于综合我的方法,我忘记了管理核心基础引用的保留计数的需要。我一直在我的 .glyphPath 中发布dealloc,但没有使用 setter 方法。正如@Sven 所怀疑的那样,我只是assign在上面的代码片段中进行了一些不太直观的发布,从而弥补了我缺乏setter 方法的不足。我现在添加了如下的 setter 方法glyphUnit

- (void)setGlyphPath:(CGPathRef)newPath
{
    if (_glyphPath != newPath)
    {
        CGPathRelease(_glyphPath);
        _glyphPath = CGPathRetain(newPath);
    }
}

添加后,我现在有了必要的保留,将我的代码片段更改为@ACB 描述的那个,并且我的代码运行良好(没有它,它显然会导致 EXC_BAD_ACCESS)。

感谢@Sven 推断我的错误并让我朝着正确的方向前进……没有双关语的意思。

于 2013-01-18T22:57:05.087 回答