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)AFAIK cf_consumedは、Appleが使用するアナライザーのバージョンではまだサポートされていません。

wrapNonRetainedFoo2)インスタンスメソッドを作成すると、不思議なことに警告が消えることに気づきました。しかし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 に答える