2011-03-11 55 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