ガ'correct'multiton実施を目的。
-
22-09-2019 - |
質問
うに呼び出すことを実施しmultitonにobjective-cイルは'?私はプログラムに'許可しない'の使用 alloc
や allocWithZone:
この決定をしないメモリを割り当てる必要ものに基づいて行われます。
知っていくことを求めたい二人のインスタンスなので私が使っているスイッチ-ケくことができるようになります。
#import "Multiton.h"
static Multiton *firstInstance = nil;
static Multiton *secondInstance = nil;
@implementation Multiton
+ (Multiton *) sharedInstanceForDirection:(enum KeyName)direction {
return [[self allocWithKey:direction] init];
}
+ (id) allocWithKey:(enum KeyName)key {
return [self allocWithZone:nil andKey:key];
}
+ (id) allocWithZone:(NSZone *)zone andKey:(enum KeyName)key {
Multiton **sharedInstance;
@synchronized(self) {
switch (key) {
case KEY_1:
sharedInstance = &firstInstance;
break;
case KEY_2:
sharedInstance = &secondInstance;
break;
default:
[NSException raise:NSInvalidArgumentException format:@"Invalid key"];
break;
}
if (*sharedInstance == nil)
*sharedInstance = [super allocWithZone:zone];
}
return *sharedInstance;
}
+ (id) allocWithZone:(NSZone *)zone {
//Do not allow use of alloc and allocWithZone
[NSException raise:NSObjectInaccessibleException format:@"Use allocWithZone:andKey: or allocWithKey:"];
return nil;
}
- (id) copyWithZone:(NSZone *)zone {
return self;
}
- (id) retain {
return self;
}
- (unsigned) retainCount {
return NSUIntegerMax;
}
- (void) release {
return;
}
- (id) autorelease {
return self;
}
- (id) init {
[super init];
return self;
}
@end
PS:んでいただこの作品だが、その作成を綺麗に:)
解決
私はシングルトン悪いアイデアと恐ろしいの4倍程度このルックスを見つけます。コードは、あなたがそれに微妙なバグを追いかけて素敵な数時間を費やすのを確認することができ、あなたはおそらくそれについて快適に感じることはありません、非常に複雑です。それはよくないね。あなたは離れて、この醜態を投げるとそんなに思考を必要としない他のいくつかの方法で、一緒にあなたのオブジェクトを配線する必要があります。
あなたはパターンのように、あなたのオブジェクトを配線するFactoryパターンに似て何かを使用することができます。工場では、これらの2つのインスタンスを作成し、必要な場所に渡すの世話をします。工場はMultitonより多くのよりシンプルになります:
@interface Factory : NSObject {
Foo *foo1, *foo2;
}
@end
@implementation Factory
- (id) init {
[super init];
foo1 = [[Foo alloc] init];
foo2 = [[Foo alloc] init];
return self;
}
もちろんあなたが一度に両方のインスタンスを作成する必要はありません。キャッシュ、遅延ロード、何でも - あなたがそこに好きなものを行うことができます。ポイントは、工場出荷時にFoo
の寿命管理を任せFoo
コードから分離されます。そして、それははるかに容易になります。必要性のFoo
が作成され、有線工場を通じて、セッターを通じてFoo
を受けることになることを他のすべてのオブジェクト¶ます:
@implementation Factory
- (id) wireSomeClass {
id instance = [[SomeClass alloc] init];
[instance setFoo:foo1];
[instance setAnotherDependency:bar];
return [instance autorelease];
}
これは、すべてのはるかに簡単なご質問からコードです。
他のヒント
オalloc.の問題点をオーバー allocを返す以前に割り当てクラスのインスタンスとしている場合+sharedInstance話[[Multiton alloc]init]...+allocはインスタンス、 -initの再初期化です! 一方でオーバーライド-initは、キャッシュのルックアップおよび呼び出しの自主的なスリリース】のご返却のキャッシュされたインスタンス.
ば 本当に の費用のようなもの+alloc(なんまいキャッシュルックアップに+sharedInstanceそして全てのクライアントから依頼を受けにアクセスのインスタンス+sharedInstanceめにalloc.
オーダーのポイント:どのようにあなたは今までに2つのインスタンスのみ、または2つのインスタンスを持つ必要があるでしょうことを知っていますか? (または、2つのインスタンスを持つようにしたい?)、正確に、の「Multiton」を有するののポイントは何ですか? (そして、それさえも言葉である?)