2013-08-16 10 views
21

Also, ziemlich einfache Frage. Ignorieren der Auswirkungen der Übernutzung des Singleton-Musters. Ich versuche ein zuverlässiges Singleton-Muster in Objective-C zu finden. Ich habe über diese kommen:Statische Klasse vs Singleton

@implementation SomeSingleTonClass 

static SomeSingleTonClass* singleInstance; 

+ (SomeSingleTonClass*)getInstance 
{ 
    static dispatch_once_t dispatchOnceToken; 

    dispatch_once(&dispatchOnceToken, ^{ 
     singleInstance = [[SomeSingleTonClass alloc] init]; 
    }); 

    return singleInstance; 
} 

- (void)someMethodOnTheInstance 
{ 
    NSLog(@"DO SOMET WORK") 
} 

@end 

Diesen Ich bin ziemlich zufrieden mit, aber es führt zu einer Menge davon:

[[SomeSingleTonClass getInstance] someMethodOnTheInstance]; 

Meine Frage ist, warum dies ist besser als eine rein statische Klasse.

@implementation SomeStaticClass 

static NSString* someStaticStateVariable; 

- (id)init 
{ 
    //Don't allow init to initialize any memory state 
    //Perhaps throw an exception to let some other programmer know 
    //not to do this 
    return nil; 
} 

+ (void)someStaticMethod 
{ 
    NSLog(@"Do Some Work"); 
} 

Alles, was Sie wirklich gewinnen, ist mild sauberer suchen Methode Anrufe. Im Grunde tauschen Sie aus dieser:

[[SomeSingleTonClass getInstance] someMethodOnTheInstance]; 

Zu diesem

[SomeStaticClass someStaticMethod]; 

Dies ist eine geringfügige Vereinfachung sicher, und man kann immer speichern Sie die Instanz in Ihrer Klasse. Das ist mehr intellektuelle Neugierde, was für ein Ziel-C-Gott pinkel ich mit statischen Klassen anstelle von Singletons? Ich bin mir sicher, dass ich nicht die erste Person sein kann, die das denkt, aber ich verspreche, ich habe zuerst eine Duplikatsuche gemacht. Die wenigen Antworten, die ich fand, schienen mir auf älteren Versionen von Kakao zu beruhen, weil selbst die besprochenen Singleton-Muster von Threading-Problemen zu leiden schienen.

+0

Ich denke, du hast Recht, aber diese Frage ist ein wenig verworren (obwohl die Antwort solide ist!). Ich werde meine verlassen, aber angesichts der Antworten in diesem Thread muss ich nicht auf Upvotes von Drummers Antwort warten. Es ist richtig. Vielen Dank! – ChrisCM

+0

Was ist eine statische Klasse? – Monolo

+0

Eine statische Klasse (es gibt wahrscheinlich einen besseren Namen) ist eine Klasse, die auf Klassenmethoden und statischen Klassenvariablen beruht, anstatt auf instanziierten Objekt- und Instanzmethoden. Dies macht es zu einem bequemen Singleton. Vor allem, wenn Sie Ihre Init-Methode codieren, um eine Ausnahme auszulösen! – ChrisCM

Antwort

1

Sie pissen keine Objective-C Götter mit einer Klasse wie dieser. Tatsächlich empfiehlt Apple, dieses Muster in einigen Fällen zu verwenden (ich denke, sie haben dies in einem der ARC-Sitzungsvideos erwähnt, wo sie gängige Entwurfsmuster besprochen und erläutert haben, wie sie diese mithilfe von ARC implementieren können).

In anderen Fällen, in denen Sie mehrere Instanzen einer Klasse haben können, aber eine Standardklasse haben möchten, müssen Sie natürlich den Ansatz der geteilten Instanz verwenden.

+0

Im Wesentlichen richtig. Siehe auch die Antwort im "Duplikat" -Link, die Martin für die Auswirkungen von jedem zur Verfügung gestellt hat. Es scheint, dass keiner der Ansätze sachlich besser oder schlechter ist, nur anders. – ChrisCM

+2

Eine Sache, auf die niemand hingewiesen hat, ist, dass ein nicht-trivialer Singleton (im Gegensatz zu einer statischen Klasse) viel mehr Dinge tun kann, da es eine legitime Instanz ist. Registriere dich für Benachrichtigungen, sei Schlüssel-Wert-beobachtet, benutzt als Datenquelle, etc. –

+0

Wenn du "dieses Muster" sagst, über welches friggin Muster sprichst du? lol. Er legte zwei verschiedene Muster in die Post. – TheJeff

3

Ich fand es bequem, eine Mischung aus beidem zu machen. Ich benutze einen Standard Singletonmuster ähnlich wie die ersten, dass die Ergebnisse in:

[[MyClass defaultInstance] doSomething]; 

Aber ich mag auch andere Instanzen derselben Klasse zu erstellen in die Lage:

MyClass *secondInstance = [[MyClass alloc] init]; 
[secondInstance doSomething]; 

Wenn ich will prägnanter Zugang Methoden auf dem Singleton-Instanz zu nennen, definiere ich Klassenmethoden wie folgt:

// class method to call a method on the singleton instance 
+ (void)doSomething 
{ 
    [[MyClass defaultInstance] doSomething]; 
} 

Also mit, dass ich verwenden kann:

[MyClass doSomething]; 
1

Das erste Beispiel scheint unnötig eine Singleton-ähnliche Instanz einer Klasse zu erstellen. Ich sage unnötig, weil aus Ihren anderen Kommentaren hervorgeht, dass die Klasse keine Eigenschaften oder Instanzvariablen deklariert. Da der Hauptzweck eines Objekts darin besteht, Speicher für den Zustand bereitzustellen, ist ein Objekt ohne Instanzvariablen selten eine nützliche Sache.

Ihr zweites Beispiel zeigt eine Klasse, die niemals instanziiert werden würde. Der Hauptzweck einer Klasse in Objective-C besteht wiederum darin, als Factory für Instanzen zu fungieren, sodass eine Klasse, die nie instanziiert wurde, nicht wirklich nützlich oder notwendig ist.

Stattdessen können Sie nur eine Reihe von C-Funktionen bereitstellen. C-Funktionen müssen überhaupt keiner Klasse zugeordnet werden.So betrachten so etwas wie dies zu tun:

static NSString* someStaticStateVariable; 

void someFunction(void) 
{ 
    NSLog(@"Do Some Work"); 
} 

Die Funktionen in sein können separate .h/.m Paar oder in der .h/.m für eine bestehende Klasse aufgenommen werden, wenn es sinnvoll, so zu tun, macht (im Allgemeinen, wenn die Funktionen eng mit den Anliegen dieser Klasse verbunden sind).

+0

Die Demonstrationen der Klasse sollten zeigen, welche Designmuster ich nur in Betracht gezogen habe, nicht die Verwendung, die ich für sie in Erwägung gezogen habe. Ich erwarte natürlich, dass meine Klassen viel mehr Staat haben, als ich in meinen vereinfachten Beispielen vorgestellt habe, wegen der Stapelüberlauffrage. – ChrisCM

+0

@ChrisCM Sie scheinen zu sagen, dass Ihre Instanzen einen Zustand haben werden, aber in Ihrem zweiten Beispiel überschreiben Sie 'init', um das Erstellen von Instanzen zu deaktivieren, so dass es offensichtlich keine Möglichkeit gibt, Objekte mit Status zu haben. Sie können einer Klasse keinen Status hinzufügen, sodass nur noch globale Variablen übrig bleiben. Auch hier benötigen Sie keine Klassen und Methoden, um globale Variablen zu verwenden. Warum also nicht einfach C-Funktionen verwenden? – jlehr

+0

Ich denke, letztlich beantwortet es die Frage nicht. Beide Lösungen haben möglicherweise den gleichen Fehler, nämlich den Zustand in statischen globalen Variablen zu speichern. Es ist das "warum/warum nicht?" dass ich neugierig bin, nicht wie. Also, als Antwort, warum nicht einfache C-Funktionen verwenden? Denn das Zuordnen von etwas zu einer Klasse ist inhärent nützlich für ein besseres Verständnis von Code. [MyDatabaseClass someFunction] sagt mir viel mehr über das, was vor sich geht als someFunction(). – ChrisCM

16

Statische Klasse: Wird verwendet, wenn Sie Dienstprogrammmethoden gruppieren, die zustandsunabhängig sind.

Singleton: Wird verwendet, wenn mehrere Methoden denselben Status haben.