En cherchant des façons d’énumérer un objet tel que NSString, je me souviens d’une nouvelle fonctionnalité dans une version de Xcode4 + qui offre un nouveau moyen d’énumérer, mais pas clairement. Quelqu'un sait ça?
OK, je me suis répondu. Je suppose que je me trompe.
C'est la nouvelle fonctionnalité que j'ai mentionnée ci-dessus:
typedef enum Language : NSUInteger{
ObjectiveC,
Java,
Ruby,
Python,
Erlang
}Language;
C'est juste une nouvelle syntaxe pour enum dans Xcode 4.4, mais je suis tellement bête de penser que nous pouvons échanger "NSUInteger" en "NSString".
Alors voici comment je trouve que ça marche:
http://longweekendmobile.com/2010/12/01/not-so-nasty-enums-in-objective-c/
// Place this in your .h file, outside the @interface block
typedef enum {
JPG,
PNG,
GIF,
PVR
} kImageType;
#define kImageTypeArray @"JPEG", @"PNG", @"GIF", @"PowerVR", nil
...
// Place this in the .m file, inside the @implementation block
// A method to convert an enum to string
-(NSString*) imageTypeEnumToString:(kImageType)enumVal
{
NSArray *imageTypeArray = [[NSArray alloc] initWithObjects:kImageTypeArray];
return [imageTypeArray objectAtIndex:enumVal];
}
// A method to retrieve the int value from the NSArray of NSStrings
-(kImageType) imageTypeStringToEnum:(NSString*)strVal
{
NSArray *imageTypeArray = [[NSArray alloc] initWithObjects:kImageTypeArray];
NSUInteger n = [imageTypeArray indexOfObject:strVal];
if(n < 1) n = JPG;
return (kImageType) n;
}
FYI. L'auteur original du deuxième exemple de code a créé une catégorie pour la gestion d'énumération. Juste ce qu'il faut pour ajouter à votre propre définition de classe NSArray.
@interface NSArray (EnumExtensions)
- (NSString*) stringWithEnum: (NSUInteger) enumVal;
- (NSUInteger) enumFromString: (NSString*) strVal default: (NSUInteger) def;
- (NSUInteger) enumFromString: (NSString*) strVal;
@end
@implementation NSArray (EnumExtensions)
- (NSString*) stringWithEnum: (NSUInteger) enumVal
{
return [self objectAtIndex:enumVal];
}
- (NSUInteger) enumFromString: (NSString*) strVal default: (NSUInteger) def
{
NSUInteger n = [self indexOfObject:strVal];
if(n == NSNotFound) n = def;
return n;
}
- (NSUInteger) enumFromString: (NSString*) strVal
{
return [self enumFromString:strVal default:0];
}
@end
Une autre manière d'utiliser struct:
extern const struct AMPlayerStateReadable
{
__unsafe_unretained NSString *ready;
__unsafe_unretained NSString *completed;
__unsafe_unretained NSString *playing;
__unsafe_unretained NSString *paused;
__unsafe_unretained NSString *broken;
} AMPlayerState;
const struct AMPlayerStateReadable AMPlayerState =
{
.ready = @"READY",
.completed = @"COMPLETE",
.playing = @"PLAYING",
.paused = @"PAUSED",
.broken = @"BROKEN"
};
Ensuite, vous pouvez utiliser comme ceci:
NSString *status = AMPlayerState.ready;
Facile à utiliser, lisible. Serait bien si quelqu'un met à jour/édite une réponse avec les avantages/inconvénients de l'approche ci-dessus.
Cela sera validé par le compilateur, afin que vous ne mélangiez pas les index par accident.
NSDictionary *stateStrings =
@{
@(MCSessionStateNotConnected) : @"MCSessionStateNotConnected",
@(MCSessionStateConnecting) : @"MCSessionStateConnecting",
@(MCSessionStateConnected) : @"MCSessionStateConnected",
};
NSString *stateString = [stateStrings objectForKey:@(state)];
var stateStrings: [MCSessionState: String] = [
MCSessionState.NotConnected : "MCSessionState.NotConnected",
MCSessionState.Connecting : "MCSessionState.Connecting",
MCSessionState.Connected : "MCSessionState.Connected"
]
var stateString = stateStrings[MCSessionState.Connected]
De récents votes à la baisse m'ont attiré l'attention, et j'aimerais ajouter que enum
est vraiment facile à utiliser avec String
maintenant:
enum HTTPMethod: String {
case GET, POST, PUT
}
HTTPMethod.GET.rawValue == "GET" // it's true
#define HLCSRestMethodGet @"GET"
#define HLCSRestMethodPost @"POST"
#define HLCSRestMethodPut @"PUT"
#define HLCSRestMethodDelete @"DELETE"
typedef NSString* HLCSRestMethod;
Je sais que ce n’est pas ce que l’OP a demandé, mais écrire du code pour implémenter enum me semble exagéré. Je considérerais enum comme une fonctionnalité du langage (à partir de C) et si je dois écrire du code, je proposerais de meilleures classes qui font plus qu'énum.
La version Swift semble être plus jolie, bien que la performance ne puisse jamais être aussi bonne.
struct LRest {
enum HTTPMethod: String {
case Get = "GET"
case Put = "PUT"
case Post = "POST"
case Delete = "DELETE"
}
struct method {
static let get = HTTPMethod.Get
static let put = HTTPMethod.Put
static let post = HTTPMethod.Post
static let delete = HTTPMethod.Delete
}
}
Je pense que vous recherchez la fonction de tableau en ligne. par exemple
@[@"stringone",@"stringtwo",@"stringthree"];
sinon, je ne suis pas sûr que vous puissiez énumérer des objets.
vous pouvez cependant avoir un tableau statique de chaînes et avoir l'objet de référence enum à index.
Voir ma réponse à enum Valeurs pour NSString (iOS) - Je pense que cela pourrait constituer une solution plus élégante à ce problème.