web-dev-qa-db-fra.com

Meilleur moyen d'enum NSString

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?

17
kimimaro

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
34
kimimaro

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.

22
Injectios

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]
9
Geri

Mise à jour en 2017

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

Réponse originale Malheureusement, j'ai fini par utiliser:


#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.

Mettre à jour

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
    }

}

8
superarts.org

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.

1
Bergasms

Voir ma réponse à enum Valeurs pour NSString (iOS) - Je pense que cela pourrait constituer une solution plus élégante à ce problème.

0
BooTooMany