silence a compiler warning about releasing a CGMutablePathRef object

旧城冷巷雨未停 提交于 2019-12-07 10:20:19

问题


I have enabled the static analyzer, but it is telling me that at the end of that execution path that object didn't get released, hence possibly causing a memory leak. I am however passing that reference to the created object to another class which will release it. I was wondering if there is a method or keyword to tell the compiled that I will release this object later.

I am looking for something like the auto-release.

By the way, I am using ARC.

I create the object like this:

CGMutablePathRef pathRef = CGPathCreateMutable();

And pass it like this:

self.flowView.pathToDraw = pathRef;

In my flowView class I have this method that will release it.

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

I already tried looking at the GCPath documentation but I had no luck.

Thanks


回答1:


Yes, there is an extension for that:

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

You may declare your method as:

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

and then Clang will recognize this (from the callsite -- it fails to check that you do in fact consume it in the definition).

You need to make sure that every selector which defines this adheres to the attribute you have applied for the selector (name).

Attributes are risky - i recommend sticking to conventions where possible, and being extra cautious when dealing with dynamic dispatch. Here's an example using ARC where the compiler can get it wrong. If the compiler gets it wrong, then the chances are good you will too because you're working against the tools that are trying to help you.

IIRC, consume is the only attribute I have used, and I use it exclusively with static dispatch.




回答2:


Why don't you just follow the normal retain/release convention? I don't see what you hope to gain.

One more call to retain and release will not make any noticeable performance difference, and it will be far more comprehensible to anybody else who ever has to read this code.

CGMutablePathRef pathRef = CGPathCreateMutable();
self.flowView.pathToDraw = pathRef;
CGPathRelease(pathRef);

-(void) setPathToDraw:(CGMutablePathRef) newPath
{
    if (pathToDraw != newPath) {
        CGPathRelease(pathToDraw);
        pathToDraw=CGPathRetain(newPath);

        [self setNeedsDisplay];
    }
}

If you insist on doing it the weird way, the other alternative is to use the cf_consumed attribute in your declaration. This explains to the analyzer that you're doing something out of the ordinary.



来源:https://stackoverflow.com/questions/9816503/silence-a-compiler-warning-about-releasing-a-cgmutablepathref-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!