2013-08-16 23 views
21

Quindi, domanda piuttosto semplice. Ignorando le implicazioni dell'eccessivo utilizzo del modello singleton. Sto cercando di trovare un singlet patter affidabile in Objective-C. Mi sono imbattuto in questo:Static Class 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 

Questo Sono abbastanza felice con ma conduce a un sacco di questo:

[[SomeSingleTonClass getInstance] someMethodOnTheInstance]; 

La mia domanda è: perché è meglio di una classe puramente statica.

@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"); 
} 

Tutto ciò che si ottiene davvero, è un metodo leggermente più pulito in cerca di chiamate di metodo. In sostanza si scambia questo:

[[SomeSingleTonClass getInstance] someMethodOnTheInstance]; 

Per questo

[SomeStaticClass someStaticMethod]; 

Questa è una semplificazione minore di sicuro, e si può sempre memorizzare l'istanza all'interno della classe. Questa è più curiosità intellettuale, quale dio Objective-C sto facendo incazzare usando classi statiche invece di singleton? Sono sicuro di non poter essere il primo a pensarlo, ma lo prometto, ho fatto prima una ricerca doppia. Le poche risposte che ho trovato mi sembravano basate su versioni precedenti del cacao, perché anche i modelli singleton discussi sembravano soffrire di problemi di threading.

+0

Penso che tu abbia ragione, ma quella domanda è un po 'contorta (anche se la risposta è solida!). Lascerò perdere il mio, ma date le risposte in quel thread, non ho bisogno di aspettare i rialzi sulla risposta di Drummer. È corretto. Grazie! – ChrisCM

+0

Cos'è una classe statica? – Monolo

+0

Una classe statica (probabilmente esiste un nome migliore) è una classe che si basa su metodi di classe e variabili di classe statiche, anziché su un oggetto istanziato e metodi di istanza. Questo è ciò che lo rende un comodo singleton. In particolare se si codifica il metodo init per generare un'eccezione! – ChrisCM

risposta

1

Stai facendo incazzare gli dei dell'Object-C con una classe del genere. In realtà, Apple consiglia di utilizzare tale modello in alcuni casi (penso che abbiano menzionato questo in uno dei video della sessione ARC, dove hanno discusso modelli di progettazione comuni e come implementarli usando ARC).

In altri casi, dove è possibile avere più istanze di una classe, ma si desidera una predefinita, è necessario utilizzare l'approccio di istanza condivisa.

+0

Essenzialmente corretto. Inoltre, vedere la risposta nel link "duplicato" fornito da Martin per le ripercussioni di ciascuno. Sembrerebbe che nessuno dei due approcci sia effettivamente migliore o peggiore, solo diverso. – ChrisCM

+2

Una cosa che nessuno ha sottolineato è che un singleton non banale (al contrario di una classe statica) può fare molte più cose, poiché è un'istanza legittima. Registrati per la notifica, sii il valore-chiave-osservato, usato come origine dati, ecc. –

+0

Quando dici "quel modello", di quale frigginato schema stai parlando? lol. Ha messo due diversi modelli nel post. – TheJeff

3

Ho trovato conveniente fare un mix di entrambi. Io uso un pattern Singleton livello simile al tuo primo che si traduce in:

[[MyClass defaultInstance] doSomething]; 

Ma voglio anche essere in grado di creare altre istanze della stessa classe:

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

Quando voglio un accesso più concisa per chiamare i metodi su l'istanza Singleton, definisco metodi di classe come segue:

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

Quindi, con questo, posso usare:

012.
[MyClass doSomething]; 
1

Il primo esempio sembra creare inutilmente un'istanza simile a un singleton di una classe. Dico inutilmente perché dai tuoi altri commenti sembra che la classe non dichiari proprietà o variabili di istanza. Dato che lo scopo fondamentale di un oggetto è fornire memoria per lo stato, un oggetto senza variabili di istanza è raramente una cosa utile.

Il secondo esempio mostra una classe che non sarebbe mai stata istanziata. Ancora una volta, lo scopo fondamentale di una classe in Objective-C è di fungere da fabbrica per le istanze, quindi una classe mai istanziata non è realmente utile o necessaria.

Invece, è possibile fornire solo un set di funzioni C. Le funzioni C non devono necessariamente essere associate a una classe.Quindi prendere in considerazione fare qualcosa di simile:

static NSString* someStaticStateVariable; 

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

Le funzioni possono essere in coppia .h/.m separata, oppure possono essere incorporati nel .h/.m per una classe esistente se ha senso farlo (generalmente, se le funzioni sono strettamente associate alle preoccupazioni di quella classe).

+0

Le dimostrazioni della classe erano di dimostrare gli schemi di progettazione che stavo considerando solo, non l'uso che stavo considerando per loro. Naturalmente mi aspetto che le mie classi abbiano molto più stato di quello che ho presentato nei miei esempi semplificati, nell'interesse della domanda di overflow dello stack. – ChrisCM

+0

@ChrisCM Sembra che tu stia dicendo che le tue istanze avranno lo stato, ma nel tuo secondo esempio, si ignora 'init' per disabilitare la creazione delle istanze, quindi ovviamente non c'è possibilità di avere oggetti con stato. Non è possibile aggiungere lo stato a una classe, quindi tutto ciò che rimane sono variabili globali. Di nuovo, non hai bisogno di classi e metodi per usare variabili globali, quindi perché non usare solo le funzioni C? – jlehr

+0

Suppongo che alla fine non risponda alla domanda. Entrambe le soluzioni risentono potenzialmente dello stesso difetto, ovvero lo stato di archiviazione in variabili globali statiche. È questo "perché/perché no?" di cui sono curioso, non come. Quindi, in risposta a perché non usare le normali funzioni C? Perché associare qualcosa a una classe è intrinsecamente utile per una comprensione più chiara del codice. [MyDatabaseClass someFunction] mi dice molto di più su cosa sta succedendo su someFunction(). – ChrisCM

16

Classe statica: utilizzato quando si desidera raggruppare metodi di utilità indipendenti dallo stato.

Singleton: utilizzato quando si dispone di più metodi che condividono uno stato.