一部のObjective-Cコードを、GCCの「式のステートメントと宣言」拡張機能 を多用するARCに変換しています({})
。
GCC拡張機能は、Objective-Cオブジェクトを作成するためにプリプロセッサマクロで使用されています。実際のマクロはかなり複雑なので、これは物事を単純化するために考案された例です。_x
私の例では、パラメータは常にNSString *
次のようになっていると仮定します。
#define f(_x) ({ NSString *x = (_x); [NSString stringWithString: x]; })
もちろん、このマクロは次のように呼び出されます。
void foo() { NSString *s = f(@"foo"); }
ARC以前の環境では、これは問題なく機能します。呼び出しによって作成されたオブジェクトstringWithString:
は自動解放されたオブジェクトであり、GCC拡張機能はそれをに割り当てますs
。
ただし、ARC(Xcode 4.4.1)に変換した後、ステートメントブロックが終了するとすぐにオブジェクトが解放されます(これは、オブジェクトをインスタンス化することで確認しましたNSLog()
)dealloc
。
次のようなタイプキャストでマクロを変更してみました。
#define f(_x) ({ NSString *x = (_x); (__autoreleasing id) [NSString stringWithString: x]; })
と
#define f(_x) ({ NSString *x = (_x); (NSString __autoreleasing *) [NSString stringWithString: x]; })
ただし、どちらの形式でもコンパイルエラーが発生します。
Explicit ownership qualifier on cast has no effect
その場合、ARCとこのGCC拡張機能には互換性がないように見えます。
これはそうですか、それとも、ARCにオブジェクトをすぐに解放しないように指示する単純なものがありませんか?
私にはいくつかのオプションがあります。現時点で最も魅力的なのは、これらすべてのマクロを__inline__
関数に変換することですが、処理するコードはかなりあります。私は本当に迅速な修正を望んでいるので、どんなアイデアでもありがたいです。