2012-02-27 6 views
13

iOSアプリにlibを書く必要があります。コンパイラでARCサポートが有効になっているかどうかはどのようにわかりますか?

if (ARC) { 
    // do nothing 
} else { 
    [myObject release]; 
} 

私はどのように操作を行うことができますよう

myObject ... 

#if ARC 
    // do nothing 
#else 
    [myObject release] 
#endif 

または実行時のプロセス:

文がしなければならない前処理は、として定義しますか?

私を助けてください!ありがとうございました。

+0

@ Suulthanこの機能には妥当な使用例があります。ライブラリのユーザーがARC対応のソースを取得してARCサポートなしでコンパイルするだけでなく、数日前に私に起こったメモリを全面的に漏らしてしまうのを防ぐようにします。つまり、質問で与えられたサンプルコードは実際には乱雑に見えます。 – zoul

+1

@zoulあなたはユーザーができることは決して準備できません。あなたのケースでは、ARCがオンの場合、単純なアサーションで十分です。ARCとMRCの両方と互換性のあるコードを作成しようとすると、読みにくい難解なコード(または混乱)で終了する必要があります。そして、読み込み不可能なコードは難しいです。 – Sulthan

+0

合意して、私が心に留めていたものです。 – zoul

答えて

28

あなたがそうのように、__has_featureを使用することができます。

#if __has_feature(objc_arc) 
// ARC is On 
#else 
// ARC is Off 
#endif 

をあなたもGCCでビルドしたい場合は(AppleのGCCは、ARCに対応していません)、あなたもコンパイラを決定するために、以下が必要になる場合があります

#if defined(__clang) 
// It's Clang 
#else 
// It's GCC 
#endif 

更新

組み合わせは、彼らは一般的な形式を取る:を0

#if defined(__clang)  

#if !defined(__has_feature) 
// idk when clang introduced this 
#error This version of clang does not support __has_feature 
#endif 

#define MON_IS_ARC_ENABLED_IN_THIS_TRANSLATION __has_feature(objc_arc) 

#else 
// for every compiler other than clang: 

#if defined(__has_feature) 
#error Another compiler supports __has_feature 
#endif 

#define MON_IS_ARC_ENABLED_IN_THIS_TRANSLATION 0 

#endif 
あなたのソースには、 #define秒の MON_IS_ARC_ENABLED_IN_THIS_TRANSLATIONを使用してください。

サポートを追加するコンパイラがサポートを追加する場合は、そのためのケースを追加する必要があります(この場合、コンパイラエラーはこの場合エラーを捕捉する可能性があります)。

これは、(コメント内の会話に基づいて)予約済み識別子の定義を回避する方法を示す余分なチェックがあります。網羅的ではなくデモンストレーションです。条件付きの__has_featureチェックを頻繁に書くことが分かっている場合は、その定義のために新しいマクロを定義して、定義を減らして単純化することができます。

+0

コンパイラのIDをチェックしないで、互換性をチェックしてください。 clangが推奨する[#ifdef __has_feature](http://clang.llvm.org/docs/LanguageExtensions.html#__has_feature_extension)を使用してください。 – Jesper

+0

ご協力いただきありがとうございます! –

+0

@Jesper私はclangの推薦を間違いと考えます。 a)失敗する(むしろ簡単に)。 b)コンパイラやインプリメンテーションのために予約されているもの、具体的にはあなたのリンクから宣言してはいけません: '#define __has_feature(x)0 //非clangコンパイラとの互換性' – justin

2

あなたは、一般的にこのようなことを行うにはしたくない:

#if ARC 
    // do nothing 
#else 
    [myObject release] 
#endif 

それは災害のためのレシピなので、このようなコードに潜む多くの微妙なバグがあります。

#if __has_feature(objc_arc) 
    #define MY_RELEASE(x) while (0) {} 
#else 
    #define MY_RELEASE(x) [x release] 
#endif 

しかし、私はしても使用することは非常に神経質に次のようになります。しかし、あなたはそのための健全なユースケースを持っていない場合、あなたはおそらくマクロとオフの方が良いだろう(!私は、おかげでジャスティンを__has_featureを知りませんでした)上記のサイトから来た

#if !defined(__clang__) || __clang_major__ < 3 
    #ifndef __bridge 
     #define __bridge 
    #endif 

    #ifndef __bridge_retain 
     #define __bridge_retain 
    #endif 

    #ifndef __bridge_retained 
     #define __bridge_retained 
    #endif 

    #ifndef __autoreleasing 
     #define __autoreleasing 
    #endif 

    #ifndef __strong 
     #define __strong 
    #endif 

    #ifndef __unsafe_unretained 
     #define __unsafe_unretained 
    #endif 

    #ifndef __weak 
     #define __weak 
    #endif 
#endif 

#if __has_feature(objc_arc) 
    #define SAFE_ARC_PROP_RETAIN strong 
    #define SAFE_ARC_RETAIN(x) (x) 
    #define SAFE_ARC_RELEASE(x) 
    #define SAFE_ARC_AUTORELEASE(x) (x) 
    #define SAFE_ARC_BLOCK_COPY(x) (x) 
    #define SAFE_ARC_BLOCK_RELEASE(x) 
    #define SAFE_ARC_SUPER_DEALLOC() 
    #define SAFE_ARC_AUTORELEASE_POOL_START() @autoreleasepool { 
    #define SAFE_ARC_AUTORELEASE_POOL_END() } 
#else 
    #define SAFE_ARC_PROP_RETAIN retain 
    #define SAFE_ARC_RETAIN(x) ([(x) retain]) 
    #define SAFE_ARC_RELEASE(x) ([(x) release]) 
    #define SAFE_ARC_AUTORELEASE(x) ([(x) autorelease]) 
    #define SAFE_ARC_BLOCK_COPY(x) (Block_copy(x)) 
    #define SAFE_ARC_BLOCK_RELEASE(x) (Block_release(x)) 
    #define SAFE_ARC_SUPER_DEALLOC() ([super dealloc]) 
    #define SAFE_ARC_AUTORELEASE_POOL_START() NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    #define SAFE_ARC_AUTORELEASE_POOL_END() [pool release]; 
#endif 

:これは、痛みの可能性は、巨大なあなたはそれを行うことができます:)

+0

ありがとう! –

関連する問題