+alloc
また、シングルトンの複数のインスタンスを割り当てないように、メソッドをオーバーライドする必要があります。
編集#3:ええと 、私は公式ドキュメントがメソッドのオーバーライドについて何を言っているかを本当に知っています +alloc
が、求められた利益を達成するためにそれを回避する方法はありません。個人的に私はそれをすることに同意しませんが、それは望ましい結果を提供することができます。
次のようになります。
static MyClass *_sharedInstance = nil;
static BOOL _bypassAllocMethod = TRUE;
+ (id)sharedInstance {
@synchronized([MyClass class]) {
if (_sharedInstance == nil) {
_sharedInstance = [[MyClass alloc] init];
}
}
return _sharedInstance;
}
+ (id)alloc {
@synchronized([MyClass class]) {
_bypassAllocMethod = FALSE; // EDIT #2
if (_sharedInstance == nil) {
_sharedInstance = [super alloc];
return _sharedInstance;
} else {
// EDIT #1 : you could throw an exception here to avoid the double allocation of the singleton class
@throw [NSException exceptionWithName:[NSString stringWithFormat:@"<%@: %p> Double allocation issue", [_sharedInstance class], _sharedInstance] reason:@"You cannot allocate the singeton class twice or more." userInfo:nil];
}
}
return nil;
}
// EDIT #2 : the init method
- (id)init {
if (_bypassAllocMethod)
@throw [NSException exceptionWithName:@"invalid allocation" reason:@"invalid allocation" userInfo:nil];
if (self = [super init]) {
}
return self
}
編集#1
ここで例外をスローする必要はありませんが、単純なnil
ポインターを返すよりも、開発者がクラスを間違った方法で使用する方が視覚的なフィードバックになります。
編集#2
開発者がクラスをインスタンス化して変更されたメソッドをバイパスしないようにするための簡単なトリックを追加しました+alloc
。その場合、割り当ては正常に機能しますが-init
、例外がスローされます。