これらの行は両方とも、@implementation
宣言の上の実装ファイルにあります。
NSString * const aVar = @"aVarStringValue";
static NSString *aVar = @"aVarStringValue";
私の知る限り、2番目のstatic
は、アプリケーションの存続期間内に1回だけ割り当てられ、この事実がパフォーマンスに貢献します。
しかし、これは、そのメモリブロックが解放されないため、本質的にメモリリークであることを意味しますか?
対照的に、最初のconst
宣言は、アクセスされるたびに割り当てられますか?
Objective-C(およびC/C++)のstatic
キーワードは、変数の可視性を示します。静的変数(メソッド内ではない)は、その特定の.m
ファイル内でのみアクセスできます。一方、静的ローカル変数は1回だけ割り当てられます。
一方、const
は、参照を変更および/または再割り当てできないことを示します。作成方法は直交しています(ただし、コンパイラーはconstを最適化できます)。
NSString
リテラルは初期化され、アプリケーションの存続期間中に破壊されることはありません。これらは、メモリの読み取り専用部分に割り当てられます。
staticは変数のスコープのみを変更し、変数の宣言または格納方法は変更しません。
どちらの場合も、コンパイラは、mach-oファイルに保存されているNSStringインスタンスの定数バージョンを作成します。したがって、どちらかのインスタンスは1つだけです(動作を変更して、mach-oのロード時に文字列が動的に作成されるようにすることができますが、インスタンスは1つだけです)。
static
は、aVar
変数をコンパイルユニット(ファイル)のスコープ内でのみ表示されるようにマークするだけです。 static
がないと、どこかのヘッダーで文字列をextern NSString *aVar;
として再宣言し、どこからでもアクセスできるようになります。
const
は直交しており、NSString参照の場合、ほとんどまったく関係ありません。
static
の必要性とconst
の位置に関するすべての可能な議論を解決するために:
C99/GNU99仕様(通常はObjective-Cコードに使用されます)によると:
static
ストレージクラス指定子です
デフォルトでファイルレベルスコープのオブジェクトには外部リンケージがあります
const
型修飾子です(型の一部です)
すぐ左のインスタンスに適用されるキーワード-つまり.
MyObj const * myVar;
--const修飾オブジェクト型への非修飾ポインタ
MyObj * const myVar;
-非修飾オブジェクト型へのconst修飾ポインタ
左端の使用法-変数ではなく、オブジェクトタイプに適用されます
const MyObj * myVar;
--const修飾オブジェクト型への非修飾ポインタTHUS:
static NSString * const myVar;
-内部リンケージを持つ不変の文字列への定数ポインタ。
static
キーワードがないと、変数名がグローバルになり、アプリケーション内で名前の競合が発生する可能性があります。