如何防止某些类型的分析仪泄漏报告?
问题描述:
我在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)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))
以供将来参考时,Xcode现在看来以支持'CF_CONSUMED'宏。至少它似乎在我的4.5预览版安装中起作用,并使分析仪警告消失。 – zoul 2012-07-27 13:39:18