私は学習目的でRedditクライアントを作成しています。定数を含むファイルが必要です。 Reddit-Prefix.pch
ファイルにファイルをインポートして、すべてのファイルで定数を使用できるようにすることを考えていました。 それは物事を行うのに良い方法ですか?また、私は研究を行って、定数を作成するためのいくつかの方法を見つけましたが、どれを使用するのかわかりません:
#define
マクロconst
static const
extern const
enum
だから、どの方法が好ましい方法ですか?慣習とは何ですか?「依存する」ことは知っていますが、私の質問はより具体的には:これらのソリューションのそれぞれのユースケースは何ですか?
また、extern const
を使用する場合、ファイルをインポートする必要がありますか、それともファイルをインポートせずに定数をグローバルに使用できますか?
論理的に結論付けることができることの1つは、カスタムエラードメインのようなものを定義するとき、enum
が最良の選択であるということです(実際に正しいでしょうか?)。しかし、他の人はどうですか?
最初の質問は、定数にどのスコープを持たせるかです。これは実際には2つの質問です。
それらが単一のクラスに固有で内部的なものである場合は、次のように、.mファイルの先頭でstatic const
として宣言します。
static NSString *const MyThingNotificationKey = @"MyThingNotificationKey";
単一のクラスに関係しているが、他のクラスでパブリック/使用する必要がある場合は、ヘッダーでextern
として宣言し、.mで定義します。
//.h
extern NSString *const MyThingNotificationKey;
//.m
NSString *const MyThingNotificationKey = @"MyThingNotificationKey";
グローバルにする必要がある場合は、ヘッダーで宣言し、対応するモジュールで、特にこれらの定数に定義します。
これらをさまざまなレベルのグローバルなレベルの異なる定数と、単に一緒に属さない異なるグローバル定数とを組み合わせて一致させることができます。欲しいです。
#define
ではありませんか?古い答えは「マクロには型情報がありません」ですが、今日のコンパイラーは、リテラル(マクロの拡張対象)と変数のすべての型チェックを行うのが非常に賢明です。
最新の答えは、デバッガーがマクロを認識しないためです。 MyThingNotificationKey
がマクロの場合、デバッガーコマンドで[myThing addObserver:self forKey:MyThingNotificationKey]
と言うことはできません。デバッガーは、変数の場合にのみそれについて知ることができます。
enum
ではありませんか?まあ、rmaddyはコメントで私にそれを打ちました:enum
は整数定数しか定義できません。シリアルID番号、ビットマスク、4バイトコードなど。
これらの目的には、enum
が最適であり、絶対に使用する必要があります。 (さらに良いのは、 NS_ENUM
およびNS_OPTIONS
マクロ を使用してください。)他のものについては、must何か他のものを使用してください。 enum
は整数以外は何もしません。
Reddit-Prefix.pchファイルにファイルをインポートして、すべてのファイルで定数を使用できるようにすることを考えていました。それは物事を行う良い方法ですか?
おそらく無害ですが、おそらく過剰です。必要な場所に定数ヘッダーをインポートします。
これらの各ソリューションのユースケースは何ですか?
#define
:かなり制限されています。正直なところ、これを定数に使用する正当な理由があるかどうかはわかりません。const
:ローカル定数に最適です。また、ヘッダーで宣言して現在定義しているものにこれを使用する必要があります。static const
:ファイル固有(またはクラス固有)の定数に最適です。extern const
:ヘッダーの定数をエクスポートするときにこれを使用する必要があります。また、
extern const
を使用する場合、ファイルをインポートする必要がありますか、それともファイルをインポートせずに定数をグローバルに使用できますか?
ファイルを使用する各ファイルまたはプレフィックスヘッダーのいずれかにファイルをインポートする必要があります。
基礎で定義され、C、C++、およびWin32の互換形式にコンパイルされるため、extern
よりも少し互換性のあるFOUNDATION_EXPORT
の使用を検討してください。
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