2012-08-14 5 views
5

シングルトンを書くのが初めてで、現在のiOSプロジェクトに新しいものを使用する必要があります。要件の1つは、それが殺されるということです。私はこれがシングルトンのデザインに反していることを知っていますが、これは実行すべき/実行できるものですか?Objective-Cシングルトンの完全割り当てを解除する

+0

定義上、シングルトンは決して再び割り当てられないため、割り当て解除の概念は意味をなさない。終了のために解体する?確かに。しかし、あなたはそれに関係なく、それに頼ることはできません。 – bbum

+0

@bbumそれは定義に依存します。私にとって、最終的な定義は、GoFの象徴的な本「クラスが1つのインスタンスしか持たないようにする」からです。それは破壊と再建を排除するものではありません。 –

+1

定義により、CocoaとiOS開発内では、 – bbum

答えて

6

もちろん、でもかまいませんが、作成することができ、不要なときにリリースされるオブジェクトを探しているなら、それは通常のオブジェクトのように聞こえるでしょう。 :)


一般に、シングルトンは独自のライフサイクルを制御します。 2つの要件(1つはシングルトンを使用し、2つは自由にリリースできる)について詳しく述べていない限り、ここでは片側の議論を行うつもりです。

シングルトンが(ファイルリソースやネットワーク接続のような)本質的にユニークな他のリソースをラップする可能性があります。これが当てはまる場合、一般にシングルトンはそのリソースの「管理者」であり、シングルトンのインターフェースを介してそのリソースの制御を公開します。

これは、シングルトンオブジェクトが1トンのメモリ(何らかのバッファ)を保持しており、必要に応じてフラッシュされていることを確認したいからです。このような場合は、必要に応じてメモリを作成および解放する各メソッドについてよりスマートにすることができます。あるいは、シングルトンに低メモリシステム通知をリッスンさせ、適切に動作させることができます。

本質的には、シングルトンオブジェクト自体が実際にリリースされたケースを構築するのは難しいでしょう。単一の基本的なオブジェクトは、メモリ内のほんの一握りのバイトしか取ることができず、ぶら下がって誰も傷つけません。

+0

既存のアプリケーションを静的ライブラリに変換しなければならず、すべてのAppDelegateロジックを最小限のコードリファクタリング用にシングルトンに変換する必要がありました。 "ライブラリアプリ"は、それをウィンドウのrootviewcontrollerにするか、別のviewcontrollerによって提示/プッシュするかのどちらかで提示する必要があります。rootviewcontrollerのシナリオでは、シングルトンは設計に真実を保持し、決して殺されることはありません。他の2つのシナリオは、なぜそれを殺すことができるのかと思います。 – MattDice

+3

@MattDice:理解していますが、これを回避する方が良いです。ライブラリの "AppDelegate"に実際に状態(プロパティ)がない場合は、すべてのメソッドを1つの機械的検索/置換でクラスメソッドに変換できます。それが状態を運んでいる(そしてそれが実質的にグローバルのコンテナになる)ならば、それをとにかく破壊する必要があるかどうかを検討してください。状態をリセットする必要がある場合、そのプロパティをデフォルト状態に戻す何らかの種類の '-reset'メソッドを追加することを検討してください。 –

+1

@MattDice:これらの "ライブラリアプリ"を複数同時にナビゲーションスタックに残しておくことができれば、独立した状態を維持したい場合はシングルトンを使用することもできないことに注意してください;この場合は、実際にリファクタリングする必要があります。 –

3

もちろん問題ありません。あなたは新しいクラスメソッドを提供します:[MyClass killSingleton];そのメソッドはシングルトンを解放し、その内部参照をnilに設定します。次回誰かが[MyClass sharedSingleton]を尋ねると、以前と同じ手順を経て作成されます。

EDIT:実際、このようなルーチンは、セレクタreleaseをオーバーライドして去ってしまうことを拒否していました。したがって、状態の下の最初のコメントのように、これは静的スコープを持つオブジェクトです。オブジェクトの保持カウントを1に保つ静的変数によって維持されます。しかし、新しいクラスメソッドを追加してivar(ARCの下)を除外し、それを解放することで、望ましい結果が得られます。静的オブジェクトのインスタンス化と解放を制御することは、クラスメソッドを介して完全に行われるため、保守とデバッグが容易です。

+1

これはもはやシングルトンではなく、<スタティックスコープを持つ通常のオブジェクトです。 – borrrden

+1

あなたのコメントは答えよりも質問に適しています。私は質問に答えるだけで、技術用語の使用について人を判断するのではない。私たちがバーでこれについて議論していたのであれば、問題が何であっても、私たちはまったく別の解決策になるだろう。 –

5

私は、これはまた、Objective-Cの中に通常のメモリ管理パッテン反するシングルトン

の設計に反する知っています。通常、オブジェクトは破棄されないように別のオブジェクトを保持し、オブジェクトを破棄できるように解放します。しかし、オブジェクトを明示的に破棄することは、他のオブジェクトが行うことではありません。

オブジェクトAがシングルトンクラスSの共有インスタンスS1を取得した場合に起こることを考えてください。AがS1を保持する場合、一部のクラスメソッドがSを解放してもS1は存在し続け、 〜にはならない。クラスが後で新しい共有インスタンスS2を作成すると、Sのインスタンスが2つ、つまりS1とS2になります。これは、最初にシングルトンを定義するプロパティに違反します。

-retainをオーバーライドして-releaseを振り回すことでこの問題を回避することはできますが、最初は存在してはいけない問題を解決するのは非常に複雑です。

可能な代替方法は、共有オブジェクトを破棄するのではなく、リセットすることです。必要に応じて、すべての属性を既知の(おそらく無効な)状態に設定し、クラスメソッドで共有オブジェクトを再初期化することができます。共有オブジェクトを使用している可能性があるすべてのオブジェクトに対するすべての影響を認識してください。

5

私が今までに書いたことのないシングルトン(完全にUI中心のコントローラのために保存される)は、シングルトンではなくリファクタリングされることになります。すべて。シングル。 1。

こうして、私はシングルトンの作成をやめました。通常のクラスと同様に、インスタンス内で状態を維持するクラスを作成し、他のインスタンスとは分離して記述します。通知が重い場合は、通知オブジェクトとして常にselfを渡します。彼らには代表者がいます。彼らは内部状態を維持します。彼らは真にグローバルな状態の外にグローバルを避けます。

そして、しばしば、私のアプリにそのクラスのインスタンスがちょうど1つ存在することがあります。その1つのインスタンスはシングルトンのように機能し、実際には、アプリケーションのデリゲートやクラスメソッド(時にはsharedInstanceという名前でさえあるかもしれません)を介して、それを保持する便利な方法を作成することさえあります。

このクラスには、一般に2つの部分に分割される引き裂きコードが含まれます。後で復旧のために現在の状態を保持するコードと、インスタンスに関連するリソースを解放するコード。

シングルトンのように便利です。必要なときに多重化される準備ができています。

1

それはシングルトンの概念に対してだが、それは私は次のことをやってしまったので、シングルトンをクリアするために必要なARCベースのプロジェクト

//ARC 
@interface Singleton : NSObject 

+ (Singleton *)sharedInstance; 
+ (void)selfDestruct; 

@end 

@implementation Singleton 

static Singleton *sharedInstance = nil; 

+ (Singleton *)sharedInstance { 
    if (sharedInstance == nil) { 
     sharedInstance = [[Singleton alloc] init]; 
    } 
    return sharedInstance; 
} 

+ (void) selfDestruct { 
    sharedInstance = nil; 
} 

@end 
+1

これは動作しません。 sharedInstanceをnilに設定した後でsharedInstanceをチェックすると、メモリに存在します。また、sharedManagerが他のオブジェクトに保持されている場合、これは何の助けにもなりません。 –

0
//This can be implemented using bool variable. If bool no create new instance. 

@interface Singleton : NSObject 

+ (Singleton *)sharedInstance; 

@end 

@implementation Singleton 

static Singleton *sharedInstance = nil; 

+ (Singleton *)sharedInstance { 

     if (!keepInstance) { 
       sharedInstance = [[Singleton alloc] init]; 
       keepInstance = YES; 
     } 
     return sharedInstance; 
} 

@end 
0

ため、次のように実装できます。

- (void)deleteSingleton{ 
@synchronized(self) { 
    if (sharedConfigSingletone != nil) { 
     sharedConfigSingletone = nil; 
    } 
} 
} 

希望します。

関連する問題