1. ホーム
  2. objective-c

[解決済み] Objective-Cで定数を作成する最も良い方法は何ですか?

2022-04-26 09:24:21

質問

学習用に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_ENUMNS_OPTIONS マクロ .) その他のものについては が必要です。 は他のものを使う。 enum は整数以外のことはできません。

その他の質問

Reddit-Prefix.pchのファイルをインポートして、すべてのファイルで定数を利用できるようにしようかと考えています。良い方法なのでしょうか?

おそらく無害でしょうが、おそらく過剰でしょう。定数ヘッダを必要な場所にインポートしてください。

それぞれの解決策には、どのようなユースケースがあるのでしょうか?

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

また extern const それとも、ファイルをインポートしなくても、定数はグローバルに利用可能なのでしょうか?

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