2012-11-28 13 views
5

Qual è il vantaggio di utilizzare questo:Perché assegnato uno zero a variabile statica di Singleton

+ (CardPainter*) sharedPainter { 
    static CardPainter* sp = nil; 

    if (nil == sp) { 
     sp = [[CardPainter alloc] init]; 
    } 

    return sp; 
} 

invece di questo:

+ (CardPainter*) sharedPainter { 
    static CardPainter* sp = [[CardPainter alloc] init]; 

    return sp; 
} 

L'inizializzazione variabile statica viene eseguita solo una volta, quindi non vedo nessun vantaggio del primo.

+3

http://stackoverflow.com/a/12304815/1861302 – melanye

+5

Il vantaggio del primo è che funziona, quest'ultimo non viene nemmeno compilato. – rmaddy

risposta

-2

Perché se non lo chiedi, inizierai a "* sp" ogni volta che chiami "sharedPainter", perdendo tutti i dati.

Quindi, se si chiede se sp è nullo e la risposta è FALSE significa che "sp" è già inizializzato e restituisce l'istanza. Se la risposta è vera, ciò significa che lo sp non è inizializzato e solo in quel caso si chiama la funzione init.

+0

Non si tratta di controllare se il puntatore è nullo, si tratta del motivo per cui non basta chiamare 'alloc init' sulla riga di inizializzazione –

+0

Beh, in realtà la dichiarazione della statica non deve essere sulla funzione sharedPainter, deve essere prima dell'implementazione . – Vertig0

+0

@PatricioIgnacioFariaValdivi: umm ... cosa? Ovviamente è possibile avere variabili statiche all'interno di una funzione – user102008

1

Bene, a livello di compilatore ci sono diversi motivi che si sovrappongono ... il più semplice da pensare è che le variabili statiche sono memorizzate in una sezione di dati dedicata della tua applicazione compilata, che è appena mappata in memoria così com'è. Quindi il compilatore deve sapere con precisione cosa è in fase di compilazione. Il risultato di qualsiasi chiamata al metodo Objective-C è imprevedibile in fase di compilazione per definizione e, in pratica, non si sa mai che qualcosa di "interessante" non si verificherà in runtime per modificare il comportamento di tale chiamata di metodo, quindi non si sapere con certezza cosa verrà restituito.

Questo è tutto un po 'diverso da ad es. C++, per vari motivi (uno dei principali è che C++ ha costruttori, mentre Objective-C non lo fa). Ma anche in C++ è ancora visto di buon occhio per diversi motivi:

  1. ordine Constructor è imprevedibile, ma è facile e comune per avere costruttori dipendono l'uno dall'altro, il che significa il programma può avere un comportamento non definito in fase di esecuzione (compresa la corruzione di dati o crash).
  2. L'inizializzazione di molti oggetti non banali può essere costosa. Fare tutto insieme al momento del lancio potrebbe essere efficiente, ma rende l'avvio della tua app lento, il che è molto peggio.

Quest'ultimo punto si applica ugualmente all'obiettivo-C. Quanto più è possibile evitare di fare al momento del lancio, e invece fare just-in-time, on-demand, tanto migliore è generalmente l'esperienza dell'utente.

[Si noti che esiste un'eccezione notevole alla regola "nessuna istanza di oggetto statico" e le stringhe del modulo @ "pippo". Quelli sono in realtà codificati nella sezione dati della tua app come istanze reali (di una speciale sottoclasse NSString) che vengono mappate al momento dell'avvio e che funzionano magicamente così com'è. Ma questo è molto attentamente architettato e il runtime del compilatore & è strettamente accoppiato su questo aspetto, per assicurarsi che tutto funzioni senza intoppi. Non è e non può essere applicato in generale. ]

Problemi correlati