2012-07-20 9 views
30

Negli ultimi strumenti, un nuovo tipo di enum s sono ora ammessi:La nuova enum in Objective-C

typedef enum CarType : NSUInteger { 
    FourDoorCarType, 
    TwoDoorCarType 
} CarType; 

La mia domanda è disponibile in parti:

  1. Perché dovrei usare questo invece del vecchio modo?

  2. Perché lo CarType appare due volte? Ho tentato di saltare il primo CarType e di lasciare la prima riga come "typedef enum : NSUInteger {" e sembra funzionare correttamente. Quali sono gli svantaggi, se ce ne sono?

  3. È possibile utilizzare alcuni tipi diversi da NSUInteger?

+6

+1 di sensibilizzazione. Non avevo sentito parlare di questa funzione. –

risposta

19
  1. Definisce esplicitamente il tipo numerico utilizzato dall'enumerazione. Questo aiuta con problemi di portabilità. Aiuta anche se hai bisogno di controllo su firmato vs non firmato

  2. Due tipi sono effettivamente definiti qui. Il primo è enum CarType e il secondo è CarType, che è un alias di enum CarType. Puoi omettere il primo CarType se lo desideri. Ciò impedisce solo a enum CarType di essere un tipo definito, ma CarType è ancora valido. Un'altra cosa comune che la gente fa è qualcosa di simile a

    typedef enum _EnumName { 
        values 
    } EnumName; 
    

    Ciò che si decide di fare qui è una questione di preferenza personale.

  3. Sì. È possibile utilizzare qualsiasi tipo numerico, anche se i valori enum devono essere in grado di adattarsi al tipo scelto.

+0

Tranne che gli identificatori che iniziano con un trattino basso seguito da una lettera maiuscola sono riservati per l'implementazione. – dreamlax

+0

Io uso 't' (per 'tag') invece del carattere di sottolineatura, ad esempio typedef enum tMyEnum {...} MyEnum; –

+0

Questo nuovo metodo consente l'uso di float/double? –

3

Per il punto 2: è la "stessa vecchia sintassi" di C: typedef <something> <alias>. Qui, something è enum <enumIdent> { <a, b, c, d, ...> }.

È possibile utilizzare lo stesso nome per enumIdent e alias, semplicemente.

37

perché questo nuovo modo si aiuta con il completamento automatico, switch, meglio, le avvertenze, rispettivamente più precise, ...

Stick con la macro ...

typedef NS_ENUM(NSUInteger, CarType) { 
    FourDoorCarType, 
    TwoDoorCarType 
}; 

... leggi per esempio https://stackoverflow.com/a/3190470/581190

NSInteger, ... che tipi di messaggi desideri?

+0

* In che modo * aiuta con completamento automatico, istruzioni switch o avvisi? –

+0

Quando si definisce enum con questa macro, viene visualizzato un avviso che non gestisce tutti i possibili casi nell'istruzione switch, ad esempio. Immagina di avere l'istruzione switch con 'case FourDoorCarType:' solo. Ti avverte che non gestisci 'TwoDoorCarType', ecc. – robertvojta

1

le risposte sarebbero qui per voi.

typedef enum MYCARTYPE { // you could drop the ": NSInteger" part to you could drop the the MYCARTYPE name as well, if you like. 
    FourDoorCarType, 
    TwoDoorCarType 
} CarType; 

Perché dovrei usare questo al posto del vecchio modo?

è possibile utilizzare il vecchio modo nella fase attuale.

Perché loCarTypeviene visualizzato due volte? Ho provato a saltare il primoCarTypee lasciare la prima riga cometypedef enum : NSUInteger {, e sembra funzionare bene. Quali sono gli svantaggi, se ce ne sono?

perché avete chiamato i enum come CarType e quindi è chiamato il nuovo tipo di typedef definizione come CarType pure. non è necessario nominare lo enum perché non si può usare il suo nome ovunque. il nome del nuovo tipo dovrebbe essere sufficiente.

Può essere utilizzato alcuni tipi diversiNSUInteger?

sì, è possibile, i tipi sono sempre NSInteger, non è necessario limitarli unsigned integer.

+0

Gli identificatori che iniziano con due caratteri di sottolineatura sono riservati e non devono essere utilizzati. Allo stesso modo, gli identificatori che iniziano con un trattino basso seguito da una lettera maiuscola sono anch'essi riservati. – dreamlax

+0

hai parzialmente ragione, questo tipo di nomi sono ** veramente ** riservati: '__MATH__' ma per gli altri ID, che inizia con due trattini bassi, non ci sono convenzioni, quindi puoi usarli come' __MATH'. – holex

+2

no, sono completamente corretto, lo standard C §7.1.3 dice: * Tutti gli identificatori che iniziano con un carattere di sottolineatura e una lettera maiuscola o un altro carattere di sottolineatura sono sempre riservati per qualsiasi uso. * – dreamlax

3

Un grande vantaggio è che è possibile inoltrare-dichiarare enumerazioni con la seguente sintassi:

enum CarType : NSUInteger; 

che aiuta evitando tra cui grandi intestazioni in altre intestazioni solo a causa delle definizioni enum.

1

Nuova NS_ENUM consente anche di inoltrare dichiarare come segue:

// Forward declaration for XYZCharacterType in other header say XYZCharacter.h 
typedef NS_ENUM(NSUInteger, XYZCharacterType); 


// Enum declaration header: "XYZEnumType.h" 
#ifndef XYZCharacterType_h 
#define XYZCharacterType_h 

typedef NS_ENUM(NSUInteger, XYZEnumType) { 
    XYZCharacterTypeNotSet, 
    XYZCharacterTypeAgent, 
    XYZCharacterTypeKiller, 
}; 

#endif /* XYZCharacterType_h */` 

Stesso come la risposta che ho postato su Forward-declare enum in Objective-C