Frage

nennen würde Sie diese Implementierung eines Multiton in Objective-c 'elegant'? Ich habe programmatisch ‚nicht zulässig‘ Verwendung von alloc und allocWithZone: weil die Entscheidung zuzuordnen oder nicht Speicherbedarf zuweisen basierend auf einem Schlüssel durchgeführt werden.

Ich weiß sicher, dass ich zur Arbeit muß mit nur zwei Instanzen, also verwende ich ‚switch-case‘ statt einer Karte an.

#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: Ich habe noch nicht, ob das funktioniert ausprobiert, aber die Zusammenstellung sauber:)

War es hilfreich?

Lösung

Ich finde Singletons eine schlechte Idee, und das sieht etwa viermal so schrecklich. Der Code ist recht komplex, können Sie sicher sein, eine schöne paar Stunden zu verbringen jagen subtile Bugs in ihm und Sie werden wahrscheinlich nie darüber wohl fühlen. Das ist nicht gut. Sie sollten sich diese Gräuel werfen und Ihre Objekte zusammen in einer anderen Art und Weise verbinden, die nicht so viel zu denken erfordert.

Wenn Sie wie Muster, Sie so etwas wie Factory-Muster verwenden können, um Ihre Objekte zu verdrahten. Die Fabrik kümmert, diese beiden Instanzen zu erstellen und sie vorbei, wo immer nötig. Und die Fabrik wird viel einfacher als Multiton sein:

@interface Factory : NSObject {
    Foo *foo1, *foo2;
}
@end

@implementation Factory

- (id) init {
    [super init];
    foo1 = [[Foo alloc] init];
    foo2 = [[Foo alloc] init];
    return self;
}

Natürlich können Sie nicht beide Instanzen auf einmal erstellen müssen. Sie können Sie es gerne etwas tun - Cache, faul Last, alles. Der Punkt verlässt das Foo Lebensdauer-Management bis zur Fabrik, getrennt vom Foo Code. Dann wird es viel einfacher. ¶ Alle anderen Objekte, die Notwendigkeit Foo wird durch Fabrik erstellt und verdrahtet werden und ihre Foo durch eine Setter erhalten:

@implementation Factory

- (id) wireSomeClass {
    id instance = [[SomeClass alloc] init];
    [instance setFoo:foo1];
    [instance setAnotherDependency:bar];
    return [instance autorelease];
}

Das ist alles viel einfacher dann der Code aus Ihrer Frage.

Andere Tipps

Nicht überschreiben alloc. Das Problem mit alloc Überschreiben einer zuvor zugeordneten Instanz der Klasse zurückzukehren, wie Sie das tun, ist, dass, wenn + sharedInstance ruft [[Multiton alloc] init] ... + alloc wird die alte Instanz zurück, dann -init wird Wieder initialisieren es! die beste Vorgehensweise weise~~POS=HEADCOMP ist -init außer Kraft zu setzen, um das Cache-Lookup und rief [self release], bevor Sie die zwischengespeicherte Instanz zurück.

Wenn Sie wirklich besorgt über die Kosten dieser zusätzlichen + alloc (es ist nicht viel), tun Sie auch Ihre Cache-Suche in + sharedInstance und dann sicherzustellen, dass alle Ihre Kunden die Instanz zugreifen durch + sharedInstance die extra alloc zu vermeiden.

Tagesordnungspunkt: Wie wissen Sie, dass Sie immer nur zwei Instanzen haben, oder müssen zwei Instanzen haben? (Oder wollen zwei Instanzen haben?) Was genau ist der Punkt einen „Multiton“ zu haben? (Und das ist auch nur ein Wort?)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top