【问题标题】:silence a compiler warning about releasing a CGMutablePathRef object使有关释放 CGMutablePathRef 对象的编译器警告静音
【发布时间】:2012-04-06 16:09:33
【问题描述】:

我启用了静态分析器,但它告诉我在该执行路径的末尾该对象没有被释放,因此可能导致内存泄漏。但是,我将对创建的对象的引用传递给另一个将释放它的类。我想知道是否有方法或关键字告诉编译我稍后会释放这个对象。

我正在寻找类似自动释放的东西。

顺便说一句,我正在使用 ARC。

我这样创建对象:

CGMutablePathRef pathRef = CGPathCreateMutable();

然后像这样传递它:

self.flowView.pathToDraw = pathRef;

在我的 flowView 类中,我有这个方法可以释放它。

-(void) setPathToDraw:(CGMutablePathRef) newPath {
    if(pathToDraw!=NULL) CGPathRelease(pathToDraw);
    pathToDraw=newPath;
    [self setNeedsDisplay];
}

我已经尝试查看 GCPath 文档,但没有运气。

谢谢

【问题讨论】:

    标签: objective-c xcode clang-static-analyzer


    【解决方案1】:

    为什么不遵循正常的保留/释放约定?我看不出你希望得到什么。

    再调用一次保留和释放将不会产生任何明显的性能差异,并且对于必须阅读此代码的任何其他人来说都将更容易理解。

    CGMutablePathRef pathRef = CGPathCreateMutable();
    self.flowView.pathToDraw = pathRef;
    CGPathRelease(pathRef);
    
    -(void) setPathToDraw:(CGMutablePathRef) newPath
    {
        if (pathToDraw != newPath) {
            CGPathRelease(pathToDraw);
            pathToDraw=CGPathRetain(newPath);
    
            [self setNeedsDisplay];
        }
    }
    

    如果您坚持以怪异的方式进行操作,另一种选择是use the cf_consumed attribute in your declaration。这向分析器说明您正在做一些不寻常的事情。

    【讨论】:

    • 这是我尝试的第一件事,但如果我在那里释放它,运行时会出现内存访问错误。
    • 那么您可能在代码的其他地方获得了另一个额外的版本。希望你能找到它!
    【解决方案2】:

    是的,有一个扩展:

    http://clang.llvm.org/docs/LanguageExtensions.html#objc_features

    您可以将您的方法声明为:

    - (void)setPathToDraw:(CGMutablePathRef) __attribute__((cf_consumed)) newPath
    

    然后 Clang 会识别出这一点(来自调用站点——它无法检查您是否确实在定义中使用了它)。

    您需要确保定义它的每个选择器都符合您为选择器(名称)应用的属性。

    属性是有风险的——我建议尽可能遵守约定,并且在处理动态调度时要格外小心。 Here's an example using ARC where the compiler can get it wrong。如果编译器出错了,那么很有可能你也会出错,因为你正在使用试图帮助你的工具。

    IIRC,consume 是我唯一使用过的属性,我只将它与静态调度一起使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-28
      • 2011-12-30
      • 2011-05-09
      相关资源
      最近更新 更多