13

私はこのコードを持っています:

- (NSString *) calculate: (uint) position {
    static NSArray * localArray = [NSArray arrayWithArray: self.container.objects ];
    // some un related code
    return obj;
}

コンパイラは、「初期化要素はコンパイル時の定数ではありません」と不平を言います。localArray に「static」を追加したときに発生しました。しかし、なぜ?

4

2 に答える 2

30

はコンパイル時の定数ではないため[NSArray arrayWithArray: self.container.objects ]、実行時に評価する必要がある式です。C および Objective-C では、static関数内の変数はコンパイル時の定数で初期化する必要がありますが、C++ および Objective-C++ はより寛大で、コンパイル時以外の定数を許可します。

コードを Objective-C++ としてコンパイルするか、次のようにリファクタリングします。

static NSArray *localArray = nil;
if (localArray == nil)
    localArray = [NSArray arrayWithArray: self.container.objects ];

とにかく、コンパイル時以外の定数で初期化された変数に対してコンパイラが内部で生成するコードにかなり似ていますstatic(実際には、値が初期化されたかどうかを示す2番目のグローバルフラグを使用します。センチネル値はこのように; この場合、それは絶対にないとnil仮定しています)。必要に応じて、コンパイラの逆アセンブリをチェックアウトできます。localArraynil

于 2012-09-06T16:52:33.483 に答える
5

実行時に既知/変更される非静的値で静的変数を初期化することはできません。

おそらく次のようにする必要があります。

static NSArray *localArray = nil;
localArray = ...;

最初の命令は、アプリのライフサイクルで 1 回実行されます。2 番目の命令は、calculate: メソッドが呼び出されるたびに実行されます。

ただし、静的変数を使用すると、適切に使用しないとバグが発生する可能性があることに注意してください。これらに不安を感じる場合は、おそらく使用しないでください。

于 2012-09-06T16:53:05.483 に答える