[解決済み] Objective-Cで定数を作成する最も良い方法は何ですか?
質問
学習用にRedditのクライアントを作成しています。その中に定数の入ったファイルが必要です。そのファイルをインポートすることを考え
Reddit-Prefix.pch
ファイルを作成し、定数をすべてのファイルで利用できるようにします。
良い方法なのでしょうか?
また、調べたところ、定数を作成する方法はいくつかあるようですが、どれを使えばいいのかわかりません。
-
#define
マクロ -
const
-
static const
-
extern const
-
enum
では、どちらの方法が好ましいのでしょうか?規約はどうなっているのでしょうか? "it depends"というのは知っていますが、より具体的に質問します。 それぞれのソリューションのユースケースをお聞かせください。
また
extern const
それとも、ファイルをインポートしなくても、定数はグローバルに利用可能なのでしょうか?
論理的に結論づけると、ひとつは
enum
は、カスタムエラルドメインのようなものを定義する際に最適な選択です(実際、私は正しいのでしょうか?) しかし、他はどうでしょうか?
どのように解決するのか?
最初の質問は、定数にどのようなスコープを持たせるかということですが、これは実際には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
は整数の定数しか定義できません。シリアル識別番号、ビットマスク、4バイトコードなどです。
そのような目的のために
enum
は素晴らしいので、絶対に使うべきです。(さらに良いのは
その
NS_ENUM
と
NS_OPTIONS
マクロ
.) その他のものについては
が必要です。
は他のものを使う。
enum
は整数以外のことはできません。
その他の質問
Reddit-Prefix.pchのファイルをインポートして、すべてのファイルで定数を利用できるようにしようかと考えています。良い方法なのでしょうか?
おそらく無害でしょうが、おそらく過剰でしょう。定数ヘッダを必要な場所にインポートしてください。
それぞれの解決策には、どのようなユースケースがあるのでしょうか?
-
#define
: かなり限定的。正直言って、定数にこれを使う理由はもうないんじゃないかと思う。 -
const
: ローカル定数に最適。また、ヘッダで宣言し、現在定義しているものにも使用する必要があります。 -
static const
: ファイル固有(またはクラス固有)の定数に最適です。 -
extern const
: ヘッダ内の定数をエクスポートするときに使用する必要があります。
また
extern const
それとも、ファイルをインポートしなくても、定数はグローバルに利用可能なのでしょうか?
使用する各ファイル、またはプレフィックスヘッダで、ファイルをインポートする必要があります。
関連
-
[解決済み】Objective-C。NULL、nil、@""の違いは何ですか?
-
[解決済み] Objective-Cの定数
-
[解決済み] const int*、const int * const、int const *の違いは何ですか?
-
[解決済み] C#のconstとreadonlyの違いは何ですか?
-
[解決済み] Objective-Cのtypedef enumとは何ですか?
-
[解決済み] Objective-Cでデリゲートを作成するにはどうしたらいいですか?
-
[解決済み] Objective-Cで、オブジェクトの種類をテストするにはどうしたらいいですか?
-
[解決済み] 「NSString *' 型のパラメータに 'const NSString *' を送ると修飾子が破棄される」警告
-
[解決済み】Objective-Cのコードをユニットテストするのに最適な方法は何ですか?
-
[解決済み】idの代わりにinstancetypeを使い始めるのは有益でしょうか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] arc4randomとarc4random_uniformの違いは何ですか?重複
-
[解決済み] Objective-Cのnil、NIL、nullの違いについて
-
[解決済み] objcの "pi "と "M_PI "の違いは何ですか?
-
[解決済み] NSStringをNSNumberに変換する方法
-
[解決済み] メソッド名と行番号を出力し、NSLogを条件付きで無効にする方法は?
-
[解決済み】"static const" vs "#define" vs "enum"
-
[解決済み】Objective-Cのシングルトンはどのように見えるべきですか?[クローズド]
-
[解決済み】isEqual:とハッシュをオーバーライドするためのベストプラクティス
-
[解決済み】コンパイルの警告:アーキテクチャi386のファイルを処理するルールがない
-
[解決済み】新しい自動リファレンスカウント機構はどのように機能するのですか?