3

Cocoaに静的変数が必要です。

Objective-Cでクラスレベルのプロパティを宣言するにはどうすればよいですか?、これまで私がいつもやってきたことに何か問題があるかどうかはわかりません。

// Foo.m
static NSString* id;
@interface Foo ()

それ以外の

// Foo.h
@interface Foo {
}

+(NSString*) id;

// Foo.m
+(NSString*) id
{
  static NSString* fooId = nil;

  if (fooId == nil)
  {
    // create id
  }

  return fooId;
}

明らかに、2番目のアプローチはIDを初期化する機会を提供します。しかし、コード内の別の場所でIDを自分で初期化すると、次のようになります。

-(NSString*) getId
{
    if (id==nil) {
      id =  ... // init goes here
    }
    return id;
}

それでは、より複雑なクラス関数アプローチとは対照的に、単純な静的宣言アプローチに何か問題がありますか?私は何が欠けていますか?

4

1 に答える 1

7

まず、あなたが求めているのはグローバル変数です。静的変数は似ていますが、少し異なります...

ヘッダー( ) ファイルstaticのいずれかの外側に宣言を配置すると、ヘッダーを含める各実装 ( ) ファイルに異なる変数が作成されます。この場合、必要なものではありません。@interface.h.m

そのstaticため、宣言では、アプリケーション実行全体の寿命を持つ変数が作成されますが、直接またはインクルードを介して、それが表示されるコンパイル単位 (実装ファイルなど) 内でのみ表示されます。

externヘッダーで使用する必要があるすべての場所に表示されるグローバル変数を作成するには:

extern NSString *id;

そして、あなたの実装では、 : なしで宣言を繰り返しますextern:

NSString *id;

グローバル変数とクラス メソッドの何が問題なのかというと、それはプログラムの設計と保守性に関する問題です。考慮すべきいくつかの点を次に示します。

  • メソッドでは、setter メソッドと getter メソッドを提供しない限り、値を変更できません。変数は常に読み書き可能です。
  • [YourClass id]名前空間の汚染: クラス メソッドは、そのクラス名 ( )とペアになっている場合にのみ有効です。変数名は、単にid;として含まれているすべての場所で有効です。idそれは両方とも名前空間を汚染し、との間の接続を失いますYourClass- これが私たちを導きます...
  • カプセル化: グローバル変数は強力なカプセル化を破り、カプセル化はプログラムの設計と保守を支援します - これは大きなトピックです。

とは言うものの、グローバルには時間と場所があり、時には...

質問が更新された後

実装で宣言されたstatic変数は、事実上「クラス変数」、つまりクラスのすべてのインスタンスで共有される変数です。

クラス変数とセッターおよびゲッタークラスメソッドの長所と短所は、インスタンス変数とプロパティとセッター/ゲッターインスタンスメソッドの長所と短所とまったく同じです。

クラス セッター/ゲッターを使用すると、読み取り/書き込みのたびに検証やその他のロジックを実行できます。メモリ管理のローカリゼーション - 簡単に言えば、あらゆるメソッドの抽象化とカプセル化の利点です。

したがって、変数を使用するかセッター/ゲッターを使用するかは、アプリケーションによって異なります。インスタンス変数を使用するか、setter/getter/property を使用するかという問題と同じです。

于 2012-10-05T01:43:25.233 に答える