2011-03-11 90 views
2

我在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参数属性让分析器知道我稍后释放对象,但似乎不起作用。

回答

2

1)AFAIK cf_consumed在Apple使用的分析器版本中仍然不受支持。

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)) 
+0

以供将来参考时,Xcode现在看来以支持'CF_CONSUMED'宏。至少它似乎在我的4.5预览版安装中起作用,并使分析仪警告消失。 – zoul 2012-07-27 13:39:18