これは、シングルトン クラスを宣言する正しい方法ではありません。(その結果、+load
メソッドとオブジェクトの保持がここでの使用法とクラッシュの理由に適合しません)
- メソッドにシングルトン インスタンスをロードして
+load
も意味がありません。必要なとき、つまり最初に要求されたとき (遅延ロード) にのみインスタンスを割り当てるのが最善であるためです。
- しかし、もっと重要なのは、
sharedSettings
メソッドで自動解放されたインスタンスを返すと、シングルトン パターンが無効になり、その目的に失敗することです。これは、自動解放プールが空になるとすぐに解放されるインスタンスを返すためです (つまり、現在の RunLoop 反復の最後です)。 -- インナーを使用されている場合はお早めに@autoreleasepool
)。それがあなたのクラッシュの原因である可能性が非常に高いです!
- の実装
dealloc
は役に立ちません。まず、その実装を呼び出すだけなsuper
ので (メソッド定義全体を避けることができます)、クラスがシングルトンであることを意図しているため、アプリが生きている間はインスタンスがメモリから解放されることはありません。
- 最後になりましたが、実装はまったくスレッドセーフではありません。
もちろん、通常はバランスを取り、またはコールでコールする必要alloc
がありinit
ます。これがメモリ管理の主なルールです。しかし、シングルトン パターンの場合、定義によると、シングルトンの共有インスタンスは、アプリケーションが稼働している限り存続します (これが主な役割です)。これはルールの例外であり、シングルトン オブジェクトを保持する sharedInstance を解放しないでください。それが生き続け、メモリから解放されないようにするためです。release
autorelease
ARC を使用しないシングルトンの正しい (レガシー) 実装の 1 つは、シングルトンに関する Apple ドキュメントで説明されているように、alloc
/ retain
/ release
/ autorelease
/メソッドをオーバーロードすることです。retainCount
しかし、実際には、このドキュメントはかなり古く (GCD が存在する前に書かれたもの)、時代遅れであり、 GCD は現在、スレッドセーフであることが保証されているより良い代替手段を提供しているため、最近ではそれを行う方法ではありません。また、非 ARC と ARC の両方とも互換性があります(後者は ARC 環境では実装できません)。だからここに行く:
@implementation ApplicationSettings
+(ApplicationSettings*)sharedInstance
{
static ApplicationSettings* sharedInstance = nil;
static dispatch_once_t once;
dispatch_once(&once, ^{ sharedInstance = [[self alloc] init]; });
return sharedInstance;
}
@end
それだけです。メソッド外のグローバル変数は必要ありません。このメソッドを宣言し、シングルトンへのアクセスが必要になるたびに使用するだけで完了です。そして、シングルトンのいくつかのインスタンス変数を埋める必要がある場合は、おそらくメソッドで行うように、通常の標準クラスで行うように、シングルトンconfigureInitialSettings
のメソッドで行うだけです。init
追加の注意:本当に厳密にしたい場合は、 alloc/init を使用してクラスの他のインスタンスの割り当て/作成を禁止しないと主張する人もいるかもしれません(また、質問で独自の実装を行うこともありません)。シングルトン: 本当に必要な場合は、複数のインスタンスを割り当てることができます。
しかし、実際には、それが真実であったとしても、これらの制約を実際に追加する理由がわかりません (また、ある日 ARC に切り替えた場合、いずれにせよこれらの制約を追加することはできません)。シングルトン パターンを探すときに本当に必要なのは、「複数のインスタンスの作成を禁止する方法」よりも「アプリケーション全体で共有される共通のインスタンス」であり、それがここにあるものです。実際、シングルトンであると主張するほとんどのクラスがそうです (NSFileManager
たとえば)。