web-dev-qa-db-ja.com

キャッシュされた変数を定義するときにobjective-cでstaticキーワードを使用する

私は次のAppleサンプルソースコードを見ています:

    /*
 Cache the formatter. Normally you would use one of the date formatter styles (such as NSDateFormatterShortStyle), but here we want a specific format that excludes seconds.
 */
static NSDateFormatter *dateFormatter = nil;
if (dateFormatter == nil) {
    dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"h:mm a"];
}

理解しようとしています:

  • なぜstaticキーワードを使用するのですか?

  • メソッドが呼び出されるたびにnilに設定した場合、これがキャッシュされた変数とどのように一致するか。

コードは、 Tableview Suiteデモ の例4からのものです。

42
Jon Swanson

静的変数は、関数を繰り返し呼び出しても、割り当てられた値を保持します。それらは基本的に、その関数にのみ「表示」されるグローバル値のようなものです。

ただし、初期化ステートメントは1回だけ実行されます。

このコードは、関数が最初に使用されるときにdateFormatterをnilに初期化します。以降の関数の呼び出しごとに、dateFormatterの値に対してチェックが行われます。設定されていない場合(これは初めてtrueになります)、新しいdateFormatterが作成されます。設定されている場合は、代わりに静的dateFormatter変数が使用されます。

静的変数に精通することは価値があります。これらは非常に便利ですが、欠点もあります(この例では、たとえばdateFormatterオブジェクトをリリースすることはできません)。

ヒント:コードにブレークポイントを設定して、何が起こっているのかを確認することが教育的な場合があります。プログラムの複雑さが増すにつれて、これは非常に貴重なスキルになります。

62
Andrew Grant

この場合、「static」は機能的に「等号の右側にあるものを毎回評価するのではなく、前の値を使用する」ことを意味します。

この大きな力を大きな責任を持って使用してください。これらは決して消えることのないオブジェクトであるため、大量のメモリを使用するリスクがあります。 NSDateFormatterを使用するこのような場合を除いて、これが適切になることはめったにありません。

16
Jim Puls

参考までに、これは、テーブルビューコントローラーで使用するために日付フォーマッターに静的を使用する方法です。

+ (NSDateFormatter *) relativeDateFormatter
{
     static NSDateFormatter *dateFormatter;
     static dispatch_once_t onceToken;
     dispatch_once(&onceToken, ^{
         //NSLog(@"Created");
         dateFormatter = [[NSDateFormatter alloc] init];
         [dateFormatter setTimeStyle:NSDateFormatterNoStyle];
         [dateFormatter setDateStyle:NSDateFormatterMediumStyle];
         NSLocale *locale = [NSLocale currentLocale];
         [dateFormatter setLocale:locale];
         [dateFormatter setDoesRelativeDateFormatting:YES];
     });
     return dateFormatter;
}
1
DogCoffee