2009-08-19 11 views
7

Mi chiedo il motivo per cui Apple sta usando (piuttosto pesantemente in CoreAnimation, ma anche altrove) costanti dichiarate come NSString * const come ad esempio kCAGravityTop invece di normali enumerazioni? Che ne dici di sicurezza del tipo in questo caso? A quanto ho capito, si potrebbe passare qualsiasi NSString a un metodo che si aspetta questa costante senza ricevere alcun avvertimento sul compilatore.Motivi per utilizzare le costanti NSString rispetto alle enumerazioni?

risposta

11

Non sono sicuro, ma suppongo che abbia a che fare con gli utenti che aggiungono le proprie estensioni e sottoclassi ad alcune delle cose di Apple. In tal caso, puoi semplicemente sovrascrivere il metodo usato e catturare il caso in cui la stringa è "MyOwnValue" e quindi fare ciò che vuoi con esso. Questo è molto più facile che dover modificare l'enum di Apple, e ti impedisce anche di rovinare tutto.

Potrebbe anche essere per rendere più semplice per Apple l'indipendenza della versione. Con l'enumerazione, se riorganizzi il loro ordine in qualche modo può causare molti problemi per i loro valori che sono stati memorizzati nella cache (per qualsiasi motivo). Se il valore dell'enum è 1 < < 3 quando viene salvato in un file, Apple aggiunge un'altra enumerazione in modo che il suo valore sia ora 1 < < 4, quindi ovviamente la cosa sbagliata viene fuori dal programma. Perché non dovrebbero stare attenti a spostare i valori dell'enum in giro, non lo so, ma penso che sia sicuramente probabile che abbiano usato NSString perché non c'è modo che il suo valore o ordine possa essere cambiato in qualsiasi versione.

+0

+1 Buona ipotesi – h4xxr

+0

Inoltre, ritengo che l'archiviazione e l'annullamento dell'archiviazione siano un fattore.Ora, con framework come Core Data che vengono utilizzati in modo molto più esteso, se vengono utilizzate le enumerazioni c'è un sacco di boxe e unboxing che possono essere scomposti se vengono usate invece le stringhe, sebbene restino alcune considerazioni per le costanti di stringa - il peso di inutili "impianto idraulico" è ridotto. – TheBasicMind

7

Sospetto che la ragione sia storica o stilistica più di ogni altra cosa. È così che sono nati i framework NeXT e che ha creato lo "stile" Cocoa. Come vantaggio di questo approccio, l'ispezione del valore nel debugger può dare un valore significativo (ad es. @ "CAGravityTop" o qualcosa di simile invece di un senza significato int). Poiché le stringhe statiche sono gestite in modo intelligente dal compilatore, il confronto può essere effettuato tramite il confronto tra puntatori piuttosto che l'uguaglianza delle stringhe (vedere la risposta di bbum), quindi c'è un calo di prestazioni trascurabile per questo approccio.

9

I tipi enumerati non possono essere estesi senza aggiungere voci aggiuntive all'interno del tipo enumerato stesso. Pertanto, è impossibile avere contenuto di enumerazione che sia trattato sia come membro formale del tipo enumerato, ma che non sia visibile durante la normale compilazione.

Prendere CoreAnimation, ad esempio. Potrebbero esserci valori utilizzati internamente che non sono supportati o resi disponibili tramite l'API pubblica per una serie di motivi; immediatamente vengono in mente i "dettagli di implementazione".

Oltre a ciò, le stringhe come costanti consentono l'estensione come implica Eli. Inoltre tendono ad essere molto più istruttivi durante il debugging. "kCAGravityTop" è molto più indicativo di, per esempio, "4".

In termini di prestazioni, c'è pochissima penalità nell'usare le stringhe. Le stringhe statiche, di cui è effettivamente composta la controparte interna di ogni dichiarazione esterna di quasi tutte le costanti di stringa, vengono gestite in modo efficiente dal compilatore e da -isEqualToString: il primo test del metodo è l'uguaglianza del puntatore - molto veloce. Non abbastanza veloce come un interruttore(), ma data la grandezza dell'esecuzione del codice implicita dalla costante, la differenza di pochi cicli tra switch() e confronto tra stringhe è irrilevante.

5

Un motivo in più ho pensato a favore di NSString è che può passati in giro ovunque id è accettato (come ad esempio userInfo o come chiavi del dizionario), mentre i tipi primitivi (enum) avrebbero bisogno di un qualche tipo di wrapper per questo

Problemi correlati