2

我在 Objective-C 中包装了某个 C API。我有一个方便的方法,它CFTypeRef从过程 API 中获取一些并从 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参数属性,让分析器知道我稍后会释放该对象,但它似乎不起作用。

4

1 回答 1

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))
于 2011-03-11T18:47:44.513 回答