160

学習目的で Reddit クライアントを作成しています。定数を含むファイルが必要です。Reddit-Prefix.pchすべてのファイルで定数を使用できるようにするために、ファイルをファイルにインポートすることを考えていました。それは物事の良い方法ですか?また、調査を行ったところ、定数を作成する方法がいくつか見つかりましたが、どれを使用すればよいかわかりません。

  • #define大きい
  • const
  • static const
  • extern const
  • enum

では、どの方法が好ましいですか?コンベンションとは何ですか?「場合による」ことはわかっていますが、より具体的な質問は次のとおりです。これらのソリューションのそれぞれのユースケースは何ですか?

また、を使用している場合extern const、ファイルをインポートする必要がありますか?そうしないと、ファイルをインポートしなくても定数がグローバルに使用可能になりますか?

私が論理的に結論できることの 1 つenumは、カスタム エラー ドメインのようなものを定義する場合は、これが最良の選択であるということです (実際にそうでしょうか?)。しかし、他の人はどうですか?

4

2 に答える 2

392

最初の質問は、定数にどのようなスコープを持たせたいかということです。これは実際には 2 つの質問です。

  • これらの定数は単一のクラスに固有のものですか、それともアプリケーション全体に使用する意味がありますか?
  • それらがクラス固有のものである場合、それらはクラスのクライアントによって使用されるのか、それともクラス内でのみ使用されるのか?

それらが単一のクラスに固有で内部的なものである場合はstatic const、次のように .m ファイルの先頭で宣言します。

static NSString *const MyThingNotificationKey = @"MyThingNotificationKey";

それらが単一のクラスに関連しているが、他のクラスで公開/使用する必要がある場合は、それらをexternヘッダーで宣言し、.m で定義します。

//.h
extern NSString *const MyThingNotificationKey;

//.m
NSString *const MyThingNotificationKey = @"MyThingNotificationKey";

それらがグローバルである必要がある場合は、それらをヘッダーで宣言し、対応するモジュールで、特にそれらの定数に対して定義します。

必要なグローバル度のレベルが異なるさまざまな定数、および単に一緒に属さないさまざまなグローバル定数に対して、これらを組み合わせて一致させることができます。欲しいです。

なぜ#defineですか?

古い答えは「マクロには型情報がありません」ですが、今日のコンパイラは、リテラル (マクロが展開するもの) と変数のすべての型チェックを行うことについて非常にスマートです。

現代の答えは、デバッガーがマクロを認識しないためです。がマクロである[myThing addObserver:self forKey:MyThingNotificationKey]場合、デバッガ コマンドで言うことはできません。MyThingNotificationKeyデバッガーは、それが変数である場合にのみ認識できます。

なぜenumですか?

まあ、rmaddy はコメントで私を打ち負かしました:enum整数定数しか定義できません。シリアル ID 番号、ビットマスク、4 バイト コードなど。

これらの目的のために、enumは優れており、絶対に使用する必要があります。(さらに良いのはNS_ENUMおよびNS_OPTIONSマクロを使用することです。) 他のものについては、別のものを使用する必要があります。enum整数以外は何もしません。

その他の質問

Reddit-Prefix.pch ファイルにファイルをインポートして、すべてのファイルで定数を使用できるようにすることを考えていました。それは物事を行う良い方法ですか?

おそらく無害ですが、おそらく過剰です。定数ヘッダーを必要な場所にインポートします。

これらの各ソリューションのユース ケースは何ですか?

  • #define:かなり限定的です。正直なところ、これを定数に使用する正当な理由があるかどうかはわかりません。
  • const: ローカル定数に最適です。また、ヘッダーで宣言し、現在定義しているものに対してこれを使用する必要があります。
  • static const: ファイル固有 (またはクラス固有) の定数に最適です。
  • extern const: ヘッダーで定数をエクスポートする場合は、これを使用する必要があります。

また、を使用している場合extern const、ファイルをインポートする必要がありますか?そうしないと、ファイルをインポートしなくても定数がグローバルに使用可能になりますか?

ファイルを使用する各ファイルまたはプレフィックスヘッダーで、ファイルをインポートする必要があります。

于 2013-06-21T05:51:14.430 に答える
9

FOUNDATION_EXPORT

Foundation で定義されており、C、C++、および Win32 の互換性のある形式にコンパイルされるFOUNDATION_EXPORTため、より互換性を高めるために使用することを検討してください。extern

NSObjCRuntime.h で定義されているとおり

#if defined(__cplusplus)
#define FOUNDATION_EXTERN extern "C"
#else
#define FOUNDATION_EXTERN extern
#endif

#if TARGET_OS_WIN32

    #if defined(NSBUILDINGFOUNDATION)
        #define FOUNDATION_EXPORT FOUNDATION_EXTERN __declspec(dllexport)
    #else
        #define FOUNDATION_EXPORT FOUNDATION_EXTERN __declspec(dllimport)
    #endif

    #define FOUNDATION_IMPORT FOUNDATION_EXTERN __declspec(dllimport)

#else
    #define FOUNDATION_EXPORT  FOUNDATION_EXTERN
    #define FOUNDATION_IMPORT FOUNDATION_EXTERN
#endif
于 2015-08-26T20:33:51.960 に答える