2009-08-21 11 views
8

Ich frage mich, wo der beste Ort ist, um Mitglieder der Singleton-Klasse zu initialisieren.Cocoa - Singleton-Objekt: Wo werden Mitgliedsvariablen initialisiert?

Ich benutze Apple grundlegende Anleitung Singleton-Implementierung. Könnten Sie bitte herausfinden, in welcher Zeile die Einträge passieren? Der Code ist der folgende:

static MyGizmoClass *sharedGizmoManager = nil; 

+ (MyGizmoClass*)sharedManager 
{ 
    @synchronized(self) { 
     if (sharedGizmoManager == nil) { 
      [[self alloc] init]; // assignment not done here 
     } 
    } 
    return sharedGizmoManager; 
} 

+ (id)allocWithZone:(NSZone *)zone 
{ 
    @synchronized(self) { 
     if (sharedGizmoManager == nil) { 
      sharedGizmoManager = [super allocWithZone:zone]; 
      return sharedGizmoManager; // assignment and return on first allocation 
     } 
    } 
    return nil; //on subsequent allocation attempts return nil 
} 

- (id)copyWithZone:(NSZone *)zone 
{ 
    return self; 
} 

- (id)retain 
{ 
    return self; 
} 

- (unsigned)retainCount 
{ 
    return UINT_MAX; //denotes an object that cannot be released 
} 

- (void)release 
{ 
    //do nothing 
} 

- (id)autorelease 
{ 
    return self; 
} 
+2

Sie möchten vielleicht http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong lesen. Möchten Sie wirklich ein Singleton, das die Freigabe überschreibt? Das maskiert nur Fehler. –

+0

Und bevor Sie Jon Hess daran erinnern, dass Sie den Apple-Dokumenten folgen: Ich schrieb diesen Beitrag speziell als Antwort auf die Apple-Dokumente. –

+0

Bemerkenswert ist auch, dass Klassen keine "Mitglieder" haben. Der nächste, den Sie erhalten können, ist eine statische Variable in der Implementierungsdatei der Klasse. Und Klassenmitglieder sind sowieso nicht das, was Sie initialisieren wollen. Was Sie sagen wollten, sind die * instance * Variablen der singleton * instance *. –

Antwort

18

Es ist wie mit den üblichen Klassen - fügen Sie diese über dem Block:

-(id)init { 
    if (self = [super init]) { 
    // do init here 
    } 

    return self; 
} 

Es wird aufgerufen, wenn Singleton ersten Mal zugegriffen wird.

+0

Wenn ich diese Init-Methode erstellen, dann wäre es direkt zugänglich, ohne durch die SharedManager, oder? Wenn ich es jetzt privat mache, wird das die init() Methode nicht übersteuern, richtig? –

+0

Ja, es ist direkt zugänglich, aber ich denke nicht, dass es sein sollte - Singleton wird sicherstellen, dass es zum ersten Mal aufgerufen wird, wenn es benötigt wird. Sie rufen einfach die [[MySingletonClass sharedClass] Nachricht] wie gewohnt ... – Rudi

+0

+1, wie von Jon Hess bemerkt, sollten Sie im Allgemeinen nicht alle diese Methoden überladen, es sei denn, Sie müssen wirklich absolut sicherstellen, dass es nur eine Instanz dieses Objekts gibt . Das ist in der Praxis ziemlich selten. Im Allgemeinen möchten Sie nur den Zugriff auf ein freigegebenes Element vereinfachen. Dazu müssen Sie lediglich die Methode + sharedInstance (oder + sharedManager oder was auch immer) implementieren, die eine statische Instanz zurückgibt und sich nicht darum kümmert, ob ein Aufrufer explizit ein eindeutiges Objekt anfordert Beispiel. –

1

Sie können sie in der init-Methode wie jede andere Klasse initialisieren.

Beachten Sie jedoch, dass wenn Ihr Singleton Mitgliedsstatus enthält, es möglicherweise nicht mehr threadsicher ist. Da ein Singleton überall in der App jederzeit erreichbar ist, kann auf es von verschiedenen Threads aus zugegriffen werden.

Verwandte Themen