5

これを使用する利点は何ですか:

+ (CardPainter*) sharedPainter {
    static CardPainter* sp = nil;

    if (nil == sp) {
        sp = [[CardPainter alloc] init];
    }

    return sp;
}

これの代わりに:

+ (CardPainter*) sharedPainter {
    static CardPainter* sp = [[CardPainter alloc] init];

    return sp;
}

静的変数の初期化は一度だけ実行されるため、前者の利点はありません。

4

2 に答える 2

0

コンパイラ レベルでは、重複する理由がいくつかあります。最も簡単に考えられるのは、静的変数がコンパイル済みアプリケーションの専用データ セクションに格納され、そのままメモリにマップされることです。したがって、コンパイラはコンパイル時にそれが何であるかを正確に知る必要があります。Objective-C のメソッド呼び出しの結果は、定義上および実際にはコンパイル時に予測できません。そのメソッド呼び出しの動作を変更するために実行時に「興味深い」何かが発生しないことは確実にわかりません。何が返されるかを確実に知っています。

これは、さまざまな理由で、たとえば C++ とは少し異なります (重要な理由の 1 つは、C++ にはコンストラクターがあり、Objective-C にはありません)。しかし、C++ でさえ、いくつかの理由でまだ眉をひそめています。

  1. コンストラクターの順序は予測できませんが、コンストラクターが相互に依存することは簡単で一般的です。つまり、実行時にプログラムが未定義の動作をする可能性があります (データの破損やクラッシュを含む)。
  2. 多くの自明でないオブジェクトの初期化は、コストがかかる可能性があります。起動時にすべてをまとめて行うのは効率的かもしれませんが、アプリの起動が遅くなり、さらに悪いことになります。

後者の点は、Objective-C にも同様に適用されます。起動時に行うことを避け、代わりにジャストインタイムのオンデマンドを行うほど、一般的にユーザー エクスペリエンスは向上します。

[「静的オブジェクト インスタンスなし」ルールには注目すべき例外が 1 つあります。それは @"foo" 形式の文字列です。これらは実際にはアプリのデータ セクションで (特別な NSString サブクラスの) 実際のインスタンスとしてエンコードされ、起動時にマップされ、魔法のようにそのまま動作します。しかし、それは非常に慎重に設計されており、コンパイラとランタイムはその側面で緊密に結合されており、すべてがスムーズに機能するようになっています. 一般的には当てはまりませんし、当てはまりません。]

于 2012-11-29T06:04:00.417 に答える
-2

尋ねなければ、「sharedPainter」を呼び出すたびに「*sp」を初期化し、データを失うからです。

したがって、sp が nil かどうかを尋ねて、答えが FALSE の場合、"sp" は既に初期化されており、インスタンスが返されます。答えが真の場合、それは sp が初期化されていないことを意味し、その場合は init 関数を呼び出します。

于 2012-11-28T21:34:11.117 に答える