如何防止某些类型的分析仪泄漏报告?

时间:2011-03-11 16:32:23

标签: objective-c memory-leaks clang-static-analyzer

我在Objective-C中包装某个C API。我有一个方便的方法,从过程API中获取一些CFTypeRef并从OOP API返回一个包装对象。此对象保留传递的CFTypeRef并在其自己的释放时释放它。便利方法如下所示:

+ (id) wrapFoo: (CFTypeRef) foo;

我有很多方法只需要获取一些CFTypeRef并返回包装对象:

- (id) doSomething {
    CFTypeRef foo = CFCreateSomeObject();
    id wrapper = [WrappingClass wrapFoo:foo];
    CFRelease(foo);
    return wrapper;
}

这有点笨拙,所以我提出了另一种方便的方法:

+ (id) wrapNonRetainedFoo: (CFTypeRef) foo {
    id wrapper = [self wrapFoo:foo]; // CFRetains foo
    CFRelease(foo);
    return wrapper;
}

现在我可以像这样重写doSomething方法:

- (id) doSomething {
    return [WrappingClass wrapNonRetainedFoo:CFCreateSomeObject()]; // XXX
}

我喜欢这个。我并不为wrapNonRetainedFoo方法感到自豪,但它不是包的公共接口的一部分,并且在几种方法中省去了几行样板代码。

缺点是静态分析器将XXX行标记为潜在泄漏。我能做得更好吗?我尝试使用cf_consumed参数属性来玩,让分析器知道我稍后会释放该对象,但它似乎不起作用。

1 个答案:

答案 0 :(得分:2)

1)Apple使用的分析仪版本仍然不支持AFAIK cf_consumed。

2)我注意到如果你使wrapNonRetainedFoo实例方法警告将神秘地消失。但由于wrap...最好是一个类方法,这对我们没用。

3)我能想到的唯一解决方案就是这个丑陋的宏(不是用于制作,而是作为概念的证明):

#define WRAP_CFTYPE(klass, valExpr) ({ CFTypeRef val = valExpr; id result = [klass wrap:val]; CFRelease(val); result; })

用法:

WrappingClass *wrapper = WRAP_CFTYPE(WrappingClass, CFArrayCreate(NULL, NULL, 0, NULL))