web-dev-qa-db-ja.com

Objective-CのconstとstaticNSStrings

これらの行は両方とも、@implementation宣言の上の実装ファイルにあります。

NSString * const aVar = @"aVarStringValue";

static NSString *aVar = @"aVarStringValue";

私の知る限り、2番目のstaticは、アプリケーションの存続期間内に1回だけ割り当てられ、この事実がパフォーマンスに貢献します。

しかし、これは、そのメモリブロックが解放されないため、本質的にメモリリークであることを意味しますか?

対照的に、最初のconst宣言は、アクセスされるたびに割り当てられますか?

45
firstresponder

Objective-C(およびC/C++)のstaticキーワードは、変数の可視性を示します。静的変数(メソッド内ではない)は、その特定の.mファイル内でのみアクセスできます。一方、静的ローカル変数は1回だけ割り当てられます。

一方、constは、参照を変更および/または再割り当てできないことを示します。作成方法は直交しています(ただし、コンパイラーはconstを最適化できます)。

NSStringリテラルは初期化され、アプリケーションの存続期間中に破壊されることはありません。これらは、メモリの読み取り専用部分に割り当てられます。

102
notnoop

staticは変数のスコープのみを変更し、変数の宣言または格納方法は変更しません。

どちらの場合も、コンパイラは、mach-oファイルに保存されているNSStringインスタンスの定数バージョンを作成します。したがって、どちらかのインスタンスは1つだけです(動作を変更して、mach-oのロード時に文字列が動的に作成されるようにすることができますが、インスタンスは1つだけです)。

staticは、aVar変数をコンパイルユニット(ファイル)のスコープ内でのみ表示されるようにマークするだけです。 staticがないと、どこかのヘッダーで文字列をextern NSString *aVar;として再宣言し、どこからでもアクセスできるようになります。

constは直交しており、NSString参照の場合、ほとんどまったく関係ありません。

49
bbum

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キーワードがないと、変数名がグローバルになり、アプリケーション内で名前の競合が発生する可能性があります。

5
Alexey Pelekh