2009-04-26 6 views
0

私はCocoa(Touch)アプリを開発しています。異なるビューとコントローラの間で保持しなければならない特定のデータ(デバイス情報やロケーションのリストなど)があります。シングルトンのエイリアスとしてのグローバル変数?

私はApp Delegateにインスタンス変数として格納することを考えましたが、デリゲートのアドレス指定はかなり面倒です(場所配列にアクセスするたびに[[[UIApplication sharedApplication] delegate] locations]と入力しても喜んではありません)デリゲートのための何らかのエイリアス(a la NSApp)を導入しましたが、NSAppを除いて私はこれを他のCocoaアプリケーションで頻繁に見ていませんでした。

私はなぜ_Stateにクラスの名前を変更し、それの単一のインスタンスは、国家と呼ばれることはありませ、また一歩行くと私のシングルトンクラスのエイリアスを導入すると考え、その代わりに[State sharedState]の?

答えて

0
#define FOO [[[UIApplication sharedApplication] delegate] locations] 
+0

ええ、定義は良い考えです。たぶんキャストで警告を避けるため – esad

1

私はおそらく、[LocationManager sharedManager]などのシングルトンを与えたLocationManagerのようなクラスを記述します。デリゲートを呼び出すと、カプセル化が解除されます(そして、そこに到達するために3つのオブジェクトを呼び出しています)。 NSAppスタイルの#defineでさえこれを修正することはできません。

+0

場所は単に 'Location'オブジェクトのシンプルな配列なので、' LocationManager'はあまりにもオーバーヘッドになりませんか?つまり、私の呼び出しは本当にコンパクトではない[[LocationManager sharedManager] locations] 'となります。 '[Location list]'と '[Location setList:] 'を通してアクセスできる配列を保持する静的変数かもしれない – esad

1

シングルトンを取得するためにメソッド呼び出しを使用する主な目的は、シングルトンを遅延して準備することです。たとえば:

static State sharedStateInstance; 

@implementation State 
+ (id)sharedState { 
    if (!sharedStateInstance) 
     sharedStateInstance = /* Allocate instance */; 
    return sharedStateInstance; 
} 
@end 

は、これは何のコードがこれまで+sharedStateを呼び出していない場合は、何のリソースがそれを作成する費やしていないことを意味します。

また、このコードは、スレッドごとに1つのインスタンスが存在することや、すべてのスレッドの共有インスタンス(初期化の前後にロックコードが必要になる)など、今後必要になる場合に改善することができます。

1

ココアがグローバルなFooオブジェクトではなく[Foo sharedFoo]の使用を奨励する理由はいくつかあります。

[Foo sharedFoo]は、初めて使用するときに自動的にインスタンス化できます。

インスタンスを大文字で命名するのは、クラスのように見えるので非常に混乱し、バグを助長します。命名の一貫性は良いObjective-Cの中心にあります。 ObjCは非常に動的なので、コンパイラはさまざまな間違いからあなたを守ることができません。整合性の良い命名と自己規律は、バグのないココアにつながるものです。

並列処理:

Foo *foo = [Foo sharedFoo]; 
Foo *foo = [[[Foo alloc] init] autorelease]; 
Foo *foo = [Bar fooAtIndex:0]; 

それらのすべての3つは同じプログラムで法的かもしれません。シングルトンインスタンスが存在するという理由だけで、他のインスタンスも存在しないというわけではありません。 NSNotificationCenterはこれの良い例です。これはシングルトンですが、追加のインスタンスを作成することもできます(その理由もあります)。

グローバル変数はグローバルに変更できます。 sharedInstanceはできません。たとえば、Stateが(クラスではなく)グローバル変数である場合、State=nilはプログラムのどこでも有効です。これはカプセル化を破り、コンパイラが捕まえることができないstate=nilの簡単なタイプミスです。 Stateがクラスの場合、コンパイラはこの簡単なエラーをキャッチできます。

非常に読みやすいコードを奨励し、非常に動的でゆるやかな型付き環境でのバグを最小限に抑えるために、多くのCocoa命名規則があります。Perlのuse strictのように、私たちが持っている小さな安全ネットをあきらめる前に、非常に注意する必要があります。

+0

あなたが言ったすべてに私は同意します。代議員。だから私は#defineエイリアスを持っていたのです – esad

+1

あなたがアプリケーションデリゲートに頻繁にアクセスしているのを見かけたら、あまりにも多くのことがあったかもしれません。アプリデリゲートに掛かっているものの多くは、他のオブジェクトに渡す必要があります。シングルトンでなければなりません。私は#defineが好きではありませんが(デバッガでの作業がより困難になっているので)、物事をよく名づける限り、必ずしも間違っているとは限りません。たとえば、#define AppDelegate [[UIApplication sharedApplication] delegate]を使用しました。あなたのFOO定義はおそらくそれがSharedLocationsと呼ばれていればOKでしょう。つまり、ココアは、短くタイプするだけで読みやすく理解しやすいよう強く奨励しています。 –

関連する問題