Konwertuj objective - C typedef na jego odpowiednik string

Zakładając, że mam typedef zadeklarowany w moim .plik h jako taki:

typedef enum {
  JSON,
  XML,
  Atom,
  RSS
} FormatType;

Chciałbym zbudować funkcję, która konwertuje wartość liczbową typedef na łańcuch znaków. Na przykład, jeśli wiadomość [self toString:JSON] została wysłana; zwróci "JSON".

Funkcja wyglądałaby mniej więcej tak:

-(NSString *) toString:(FormatType)formatType {
  //need help here
  return [];
}

Nawiasem mówiąc, jeśli spróbuję tej składni

[self toString:FormatType.JSON];

Aby przekazać wartość typedef do metody, dostaję błąd. Co przegapiłem?

Author: craig, 2009-07-08

20 answers

To jest naprawdę pytanie C, nie specyficzne dla Objective-C (które jest supersetem języka C). Liczby w C są reprezentowane jako liczby całkowite. Więc musisz napisać funkcję, która zwraca łańcuch o podanej wartości enum. Można to zrobić na wiele sposobów. Tablica łańcuchów takich, że wartość enum może być używana jako indeks do tablicy lub struktury mapy (np. an NSDictionary), która mapuje wartość enum do pracy łańcuchowej, ale uważam, że te podejścia nie są tak jasne jak funkcja, która sprawia, że konwersja jawna (i podejście tablicowe, chociaż klasyczny sposób C jest niebezpieczny, jeśli wartości enum nie są sprzeczne z 0). Coś takiego by działało:

- (NSString*)formatTypeToString:(FormatType)formatType {
    NSString *result = nil;

    switch(formatType) {
        case JSON:
            result = @"JSON";
            break;
        case XML:
            result = @"XML";
            break;
        case Atom:
            result = @"Atom";
            break;
        case RSS:
            result = @"RSS";
            break;
        default:
            [NSException raise:NSGenericException format:@"Unexpected FormatType."];
    }

    return result;
}

Twoje powiązane pytanie dotyczące poprawnej składni dla wartości enum polega na tym, że używasz tylko wartości (np. JSON), a nie sytax FormatType.JSON. FormatType jest typem i wartościami enum (np. JSON, XML, itd.) są wartościami, które można przypisać do tego typu.

 123
Author: Barry Wark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-15 19:09:26

Nie możesz tego zrobić łatwo. W C i Objective-C, enums są tak naprawdę tylko gloryfikowanymi stałymi całkowitymi. Będziesz musiał wygenerować tabelę nazw samodzielnie (lub z jakimś nadużyciem preprocesora). Na przykład:

// In a header file
typedef enum FormatType {
    JSON,
    XML,
    Atom,
    RSS
} FormatType;

extern NSString * const FormatType_toString[];

// In a source file
// initialize arrays with explicit indices to make sure 
// the string match the enums properly
NSString * const FormatType_toString[] = {
    [JSON] = @"JSON",
    [XML] = @"XML",
    [Atom] = @"Atom",
    [RSS] = @"RSS"
};
...
// To convert enum to string:
NSString *str = FormatType_toString[theEnumValue];

Niebezpieczeństwo takiego podejścia polega na tym, że jeśli kiedykolwiek zmienisz enum, musisz pamiętać o zmianie tablicy nazw. Możesz rozwiązać ten problem z nadużyciami preprocesora, ale jest to trudne i brzydkie.

Należy również zauważyć, że zakłada się, że masz poprawną stałą enum. Jeśli masz wartość całkowitą z niezaufanego źródła, dodatkowo musisz sprawdzić, czy twoja stała jest poprawna, np. przez włączenie wartości "past max" do twojego enum, lub przez sprawdzenie, czy jest mniejsza niż długość tablicy, sizeof(FormatType_toString) / sizeof(FormatType_toString[0]).

 121
Author: Adam Rosenfield,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-24 16:10:14

Moje rozwiązanie:

edit: dodałem jeszcze lepsze rozwiązanie na końcu, używając nowoczesnego Obj-C

1.
Umieść nazwy jako klucze w tablicy.
Upewnij się, że indeksy są odpowiednimi enumami, i we właściwej kolejności (wyjątek w przeciwnym wypadku).
Uwaga: names jest właściwością zsyntetyzowaną jako * _names*;

Kod nie był sprawdzany do kompilacji, ale użyłem tej samej techniki w mojej aplikacji.

typedef enum {
  JSON,
  XML,
  Atom,
  RSS
} FormatType;

+ (NSArray *)names
{
    static NSMutableArray * _names = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _names = [NSMutableArray arrayWithCapacity:4];
        [_names insertObject:@"JSON" atIndex:JSON];
        [_names insertObject:@"XML" atIndex:XML];
        [_names insertObject:@"Atom" atIndex:Atom];
        [_names insertObject:@"RSS" atIndex:RSS];
    });

    return _names;
}

+ (NSString *)nameForType:(FormatType)type
{
    return [[self names] objectAtIndex:type];
}


//

2.
używając nowoczesnego Obj-C ty możemy użyć słownika, aby powiązać opisy z kluczami w enum.
porządek nie ma znaczenia .

typedef NS_ENUM(NSUInteger, UserType) {
    UserTypeParent = 0,
    UserTypeStudent = 1,
    UserTypeTutor = 2,
    UserTypeUnknown = NSUIntegerMax
};  

@property (nonatomic) UserType type;

+ (NSDictionary *)typeDisplayNames
{
    return @{@(UserTypeParent) : @"Parent",
             @(UserTypeStudent) : @"Student",
             @(UserTypeTutor) : @"Tutor",
             @(UserTypeUnknown) : @"Unknown"};
}

- (NSString *)typeDisplayName
{
    return [[self class] typeDisplayNames][@(self.type)];
}


Usage (in a class instance method):

NSLog(@"%@", [self typeDisplayName]);


 48
Author: Yariv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-18 20:33:33

Połączenie @ AdamRosenfield odpowiedź, komentarz @ Christoph i kolejny trick do obsługi zwykłych C enums proponuję:

// In a header file
typedef enum {
  JSON = 0,         // explicitly indicate starting index
  XML,
  Atom,
  RSS,

  FormatTypeCount,  // keep track of the enum size automatically
} FormatType;
extern NSString *const FormatTypeName[FormatTypeCount];


// In a source file
NSString *const FormatTypeName[FormatTypeCount] = {
  [JSON] = @"JSON",
  [XML] = @"XML",
  [Atom] = @"Atom",
  [RSS] = @"RSS",
};


// Usage
NSLog(@"%@", FormatTypeName[XML]);

W najgorszym przypadku-np. jeśli zmienisz enum, ale zapomnisz zmienić tablicę nazw-zwróci ona nil dla tego klucza.

 28
Author: Max O,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-11 23:16:55

Zdefiniuj typedef enum w nagłówku klasy:

typedef enum {
    IngredientType_text  = 0,
    IngredientType_audio = 1,
    IngredientType_video = 2,
    IngredientType_image = 3
} IngredientType;

Napisz taką metodę w klasie:

+ (NSString*)typeStringForType:(IngredientType)_type {
   NSString *key = [NSString stringWithFormat:@"IngredientType_%i", _type];
   return NSLocalizedString(key, nil);
}

Mieć łańcuchy wewnątrz Localizable.strings file:

/* IngredientType_text */
"IngredientType_0" = "Text";
/* IngredientType_audio */
"IngredientType_1" = "Audio";
/* IngredientType_video */
"IngredientType_2" = "Video";
/* IngredientType_image */
"IngredientType_3" = "Image";
 12
Author: kitschmaster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-09 09:15:48

Użyłbym tokena # string kompilatora (wraz z makrami, aby wszystko było bardziej kompaktowe):

#define ENUM_START              \
            NSString* ret;      \
            switch(value) {

#define ENUM_CASE(evalue)       \
            case evalue:        \
                ret = @#evalue; \
                break;

#define ENUM_END                \
            }                   \
            return ret;

NSString*
_CvtCBCentralManagerStateToString(CBCentralManagerState value)
{
    ENUM_START
        ENUM_CASE(CBCentralManagerStateUnknown)
        ENUM_CASE(CBCentralManagerStateResetting)
        ENUM_CASE(CBCentralManagerStateUnsupported)
        ENUM_CASE(CBCentralManagerStateUnauthorized)
        ENUM_CASE(CBCentralManagerStatePoweredOff)
        ENUM_CASE(CBCentralManagerStatePoweredOn)
    ENUM_END
}
 11
Author: Pete,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-12 05:58:05

Podoba mi się {[1] } sposób robienia tego:

// Umieść to w swoim .plik h, poza blokiem @ interface

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];
}

źródło (źródło nie jest już dostępne)

 8
Author: lindon fox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-20 07:07:14

Zrobiłem swego rodzaju mieszankę wszystkich rozwiązań znalezionych na tej stronie, aby stworzyć moje, jest to rodzaj obiektowego rozszerzenia enum lub coś.

W rzeczywistości, jeśli potrzebujesz więcej niż stałych (tj. liczb całkowitych), prawdopodobnie potrzebujesz obiektu modelu (wszyscy mówimy o MVC, prawda?)

Po prostu zadaj sobie pytanie przed użyciem tego, mam rację, czy w rzeczywistości nie potrzebujesz prawdziwego obiektu modelu, zainicjowanego z webservice, plist, bazy danych SQLite lub CoreData ?

Anyway oto kod (MPI jest dla "inicjałów mojego projektu", każdy używa tego lub swojej nazwy, wydaje się): {]}

MyWonderfulType.h :

typedef NS_ENUM(NSUInteger, MPIMyWonderfulType) {
    MPIMyWonderfulTypeOne = 1,
    MPIMyWonderfulTypeTwo = 2,
    MPIMyWonderfulTypeGreen = 3,
    MPIMyWonderfulTypeYellow = 4,
    MPIMyWonderfulTypePumpkin = 5
};

#import <Foundation/Foundation.h>

@interface MyWonderfulType : NSObject

+ (NSString *)displayNameForWonderfulType:(MPIMyWonderfulType)wonderfulType;
+ (NSString *)urlForWonderfulType:(MPIMyWonderfulType)wonderfulType;

@end

I MyWonderfulType.m:

#import "MyWonderfulType.h"

@implementation MyWonderfulType

+ (NSDictionary *)myWonderfulTypeTitles
{
    return @{
             @(MPIMyWonderfulTypeOne) : @"One",
             @(MPIMyWonderfulTypeTwo) : @"Two",
             @(MPIMyWonderfulTypeGreen) : @"Green",
             @(MPIMyWonderfulTypeYellow) : @"Yellow",
             @(MPIMyWonderfulTypePumpkin) : @"Pumpkin"
             };
}

+ (NSDictionary *)myWonderfulTypeURLs
{
    return @{
             @(MPIMyWonderfulTypeOne) : @"http://www.theone.com",
             @(MPIMyWonderfulTypeTwo) : @"http://www.thetwo.com",
             @(MPIMyWonderfulTypeGreen) : @"http://www.thegreen.com",
             @(MPIMyWonderfulTypeYellow) : @"http://www.theyellow.com",
             @(MPIMyWonderfulTypePumpkin) : @"http://www.thepumpkin.com"
             };
}

+ (NSString *)displayNameForWonderfulType:(MPIMyWonderfulType)wonderfulType {
    return [MPIMyWonderfulType myWonderfulTypeTitles][@(wonderfulType)];
}

+ (NSString *)urlForWonderfulType:(MPIMyWonderfulType)wonderfulType {
    return [MPIMyWonderfulType myWonderfulTypeURLs][@(wonderfulType)];
}


@end
 6
Author: dulgan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-03 08:12:05

Poprawiono odpowiedź @yar1vn poprzez opuszczenie zależności ciągów:

#define VariableName(arg) (@""#arg)

typedef NS_ENUM(NSUInteger, UserType) {
    UserTypeParent = 0,
    UserTypeStudent = 1,
    UserTypeTutor = 2,
    UserTypeUnknown = NSUIntegerMax
};  

@property (nonatomic) UserType type;

+ (NSDictionary *)typeDisplayNames
{
    return @{@(UserTypeParent) : VariableName(UserTypeParent),
             @(UserTypeStudent) : VariableName(UserTypeStudent),
             @(UserTypeTutor) : VariableName(UserTypeTutor),
             @(UserTypeUnknown) : VariableName(UserTypeUnknown)};
}

- (NSString *)typeDisplayName
{
    return [[self class] typeDisplayNames][@(self.type)];
}

Tak więc po zmianie nazwy wpisu enum zostanie zmieniony odpowiedni ciąg znaków. Przydatne w przypadku, gdy nie zamierzasz pokazać tego ciągu użytkownikowi.

 4
Author: Bohdan Orlov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-26 15:01:25

Inne rozwiązanie:

typedef enum BollettinoMavRavTypes {
    AMZCartServiceOperationCreate,
    AMZCartServiceOperationAdd,
    AMZCartServiceOperationGet,
    AMZCartServiceOperationModify
} AMZCartServiceOperation;

#define AMZCartServiceOperationValue(operation) [[[NSArray alloc] initWithObjects: @"CartCreate", @"CartAdd", @"CartGet", @"CartModify", nil] objectAtIndex: operation];

W swojej metodzie możesz użyć:

NSString *operationCheck = AMZCartServiceOperationValue(operation);
 3
Author: kennymuse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-10 10:39:16

Miałem duży wyliczony typ i chciałem go przekonwertować na NSDictionary lookup. Skończyło się na użyciu sed z terminala OSX jako:

$ sed -E 's/^[[:space:]]{1,}([[:alnum:]]{1,}).*$/  @(\1) : @"\1",/g' ObservationType.h

Które można odczytać jako: 'przechwyć pierwsze słowo w linii i wypisz @(słowo): @ "słowo", '

Ten regex konwertuje enum w pliku nagłówkowym o nazwie 'ObservationType.h", który zawiera:

typedef enum : int { 
    ObservationTypePulse = 1,
    ObservationTypeRespRate = 2,
    ObservationTypeTemperature = 3,
    .
    .
}

W coś takiego:

    @(ObservationTypePulse) : @"ObservationTypePulse",
    @(ObservationTypeRespRate) : @"ObservationTypeRespRate",
    @(ObservationTypeTemperature) : @"ObservationTypeTemperature",
    .
    .

, które następnie można zapakować w metodę wykorzystującą nowoczesną składnię objective-c @{ } (Jak wyjaśniono @yar1vn powyżej) aby utworzyć NSDictionary lookup:

-(NSDictionary *)observationDictionary
{
    static NSDictionary *observationDictionary;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        observationDictionary = [[NSDictionary alloc] initWithDictionary:@{
                                 @(ObservationTypePulse) : @"ObservationTypePulse",
                                 @(ObservationTypeRespRate) : @"ObservationTypeRespRate",
                                 .
                                 .
                                 }];
    });
    return observationDictionary;
}

Płyta kotła dispatch_once ma na celu zapewnienie, że zmienna statyczna zostanie zainicjowana w sposób bezpieczny dla wątku.

Uwaga: znalazłem wyrażenie regex sed na OSX odd - gdy próbowałem użyć +, aby dopasować "jeden lub więcej", nie działało i musiałem uciekać się do używania {1,} jako zamiennika

 2
Author: Nick Ager,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-17 14:25:26

Używam wariacji na temat odpowiedzi Barry ' ego walka, że w kolejności ważności:

  1. pozwala kompilatorowi sprawdzić brakujące klauzule case (nie może, jeśli masz klauzulę domyślną).
  2. używa typowej nazwy Objective-C (zamiast nazwy podobnej do Javy).
  3. podnosi szczególny wyjątek.
  4. jest krótszy.

EG:

- (NSString*)describeFormatType:(FormatType)formatType {    
    switch(formatType) {
        case JSON:
            return @"JSON";
        case XML:
            return @"XML";
        case Atom:
            return @"Atom";
        case RSS:
            return @"RSS";
    }
    [NSException raise:NSInvalidArgumentException format:@"The given format type number, %ld, is not known.", formatType];
    return nil; // Keep the compiler happy - does not understand above line never returns!
}
 2
Author: Howard Lovatt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-20 08:11:35

@pixel dodał tu najbardziej błyskotliwą odpowiedź: https://stackoverflow.com/a/24255387/1364257 Proszę, głosujcie na niego!

Używa schludnego makra X z lat 60. (zmieniłem trochę jego kod na nowoczesny obiekt)

#define X(a, b, c) a b,
enum ZZObjectType {
    XXOBJECTTYPE_TABLE
};
typedef NSUInteger TPObjectType;
#undef X

#define XXOBJECTTYPE_TABLE \
X(ZZObjectTypeZero, = 0, @"ZZObjectTypeZero") \
X(ZZObjectTypeOne, , @"ZZObjectTypeOne") \
X(ZZObjectTypeTwo, , @"ZZObjectTypeTwo") \
X(ZZObjectTypeThree, , @"ZZObjectTypeThree")

+ (NSString*)nameForObjectType:(ZZObjectType)objectType {
#define X(a, b, c) @(a):c, 
    NSDictionary *dict = @{XXOBJECTTYPE_TABLE};
#undef X
    return dict[objectType];
}
To wszystko. Czysto i schludnie. Dzięki @ pixel! https://stackoverflow.com/users/21804/pixel
 2
Author: voiger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:17:53

Połączyłem tu kilka podejść. Podoba mi się pomysł preprocesora i zindeksowanej listy.

Nie ma dodatkowej dynamicznej alokacji, a ze względu na inlining kompilator może być w stanie zoptymalizować wyszukiwanie.

typedef NS_ENUM(NSUInteger, FormatType) { FormatTypeJSON = 0, FormatTypeXML, FormatTypeAtom, FormatTypeRSS, FormatTypeCount };

NS_INLINE NSString *FormatTypeToString(FormatType t) {
  if (t >= FormatTypeCount)
    return nil;

#define FormatTypeMapping(value) [value] = @#value

  NSString *table[FormatTypeCount] = {FormatTypeMapping(FormatTypeJSON),
                                      FormatTypeMapping(FormatTypeXML),
                                      FormatTypeMapping(FormatTypeAtom),
                                      FormatTypeMapping(FormatTypeRSS)};

#undef FormatTypeMapping

  return table[t];
}
 2
Author: keller_k1nd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-22 11:21:36

Po pierwsze, jeśli chodzi o FormatType.JSON: JSON nie jest członkiem FormatType, jest to możliwa wartość tego typu. FormatType nie jest nawet typem złożonym - jest skalarem.

Po Drugie, jedynym sposobem na to jest utworzenie tabeli mapowania. Bardziej powszechnym sposobem, aby to zrobić w Objective-C jest utworzenie szeregu stałych odnoszących się do Twoich "symboli" , więc masz NSString *FormatTypeJSON = @"JSON" i tak dalej.

 1
Author: Chuck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-07 21:45:09

Poniżej przedstawiono rozwiązanie takie, że dodanie nowego enum wymaga tylko edycja jednowierszowa, podobna do dodawania pojedynczej linii na liście enum {}.

//------------------------------------------------------------------------------
// enum to string example
#define FOR_EACH_GENDER(tbd) \
        tbd(GENDER_MALE) \
        tbd(GENDER_FEMALE) \
        tbd(GENDER_INTERSEX) \

#define ONE_GENDER_ENUM(name) name,
enum
{
    FOR_EACH_GENDER(ONE_GENDER_ENUM)
    MAX_GENDER
};

#define ONE_GENDER(name) #name,
static const char *enumGENDER_TO_STRING[] = 
{
    FOR_EACH_GENDER(ONE_GENDER)
};

// access string name with enumGENDER_TO_STRING[value]
// or, to be safe converting from a untrustworthy caller
static const char *enumGenderToString(unsigned int value)
{
    if (value < MAX_GENDER)
    {
        return enumGENDER_TO_STRING[value];
    }
    return NULL;
}

static void printAllGenders(void)
{
    for (int ii = 0;  ii < MAX_GENDER;  ii++)
    {
        printf("%d) gender %s\n", ii, enumGENDER_TO_STRING[ii]);
    }
}

//------------------------------------------------------------------------------
// you can assign an arbitrary value and/or information to each enum,
#define FOR_EACH_PERSON(tbd) \
        tbd(2, PERSON_FRED,     "Fred",     "Weasley", GENDER_MALE,   12) \
        tbd(4, PERSON_GEORGE,   "George",   "Weasley", GENDER_MALE,   12) \
        tbd(6, PERSON_HARRY,    "Harry",    "Potter",  GENDER_MALE,   10) \
        tbd(8, PERSON_HERMIONE, "Hermione", "Granger", GENDER_FEMALE, 10) \

#define ONE_PERSON_ENUM(value, ename, first, last, gender, age) ename = value,
enum
{
    FOR_EACH_PERSON(ONE_PERSON_ENUM)
};

typedef struct PersonInfoRec
{
    int value;
    const char *ename;
    const char *first;
    const char *last;
    int gender;
    int age;
} PersonInfo;

#define ONE_PERSON_INFO(value, ename, first, last, gender, age) \
                     { ename, #ename, first, last, gender, age },
static const PersonInfo personInfo[] = 
{
    FOR_EACH_PERSON(ONE_PERSON_INFO)
    { 0, NULL, NULL, NULL, 0, 0 }
};
// note: if the enum values are not sequential, you need another way to lookup
// the information besides personInfo[ENUM_NAME]

static void printAllPersons(void)
{
    for (int ii = 0;  ;  ii++)
    {
        const PersonInfo *pPI = &personInfo[ii];
        if (!pPI->ename)
        {
            break;
        }
        printf("%d) enum %-15s  %8s %-8s %13s %2d\n",
            pPI->value, pPI->ename, pPI->first, pPI->last,
            enumGenderToString(pPI->gender), pPI->age);
    }
}
 1
Author: fredwork,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-21 08:58:54

Biorąc pod uwagę definicję enum jak:

typedef NS_ENUM(NSInteger, AssetIdentifier) {
    Isabella,
    William,
    Olivia
};

Możemy zdefiniować makro, aby przekonwertować wartość enum na odpowiadający jej ciąg znaków, jak pokazano poniżej.

#define AssetIdentifier(asset) \
^(AssetIdentifier identifier) { \
switch (identifier) { \
case asset: \
default: \
return @#asset; \
} \
}(asset)

Instrukcja switch używana w bloku służy do sprawdzania typu, a także do automatycznego uzupełniania obsługi w Xcode.

Tutaj wpisz opis obrazka Tutaj wpisz opis obrazka

 1
Author: ylin0x81,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-08 07:31:39

Wiele odpowiedzi jest całkiem dobrych.

Jeśli szukasz ogólnego, Objective C rozwiązania, które używa niektórych makr...

Kluczową cechą jest to, że używa enum jako indeksu do statycznej tablicy stałych NSString. sama tablica jest owinięta w funkcję, aby uczynić ją bardziej podobną do pakietu funkcji NSStringFromXXX rozpowszechnionych w API Apple.

Będziesz musiał #import "NSStringFromEnum.h" znaleźć tutaj http://pastebin.com/u83RR3Vk

[edytuj] również potrzebuje #import "SW+Variadic.h" znaleźć tutaj http://pastebin.com/UEqTzYLf

Przykład 1: Całkowicie zdefiniuj nowy typ enum, używając konwerterów łańcuchów.

W myfile.h


 #import "NSStringFromEnum.h"

 #define define_Dispatch_chain_cmd(enum)\
 enum(chain_done,=0)\
 enum(chain_entry)\
 enum(chain_bg)\
 enum(chain_mt)\
 enum(chain_alt)\
 enum(chain_for_c)\
 enum(chain_while)\
 enum(chain_continue_for)\
 enum(chain_continue_while)\
 enum(chain_break_for)\
 enum(chain_break_while)\
 enum(chain_previous)\
 enum(chain_if)\
 enum(chain_else)\


interface_NSString_Enum_DefinitionAndConverters(Dispatch_chain_cmd)

W myfile.m:


 #import "myfile.h"

 implementation_NSString_Enum_Converters(Dispatch_chain_cmd)

Do użycia :

NSString *NSStringFromEnumDispatch_chain_cmd(enum Dispatch_chain_cmd value);

NSStringFromEnumDispatch_chain_cmd(chain_for_c) returns @"chain_for_c"

  enum Dispatch_chain_cmd enumDispatch_chain_cmdFromNSString(NSString *value);

enumDispatch_chain_cmdFromNSString(@"chain_previous") returns chain_previous

Przykład 2: Podaj procedury konwersji dla istniejącego enum pokazuje również użycie ciągu ustawień i zmianę nazwy typename używanego w funkcje.

W myfile.h


 #import "NSStringFromEnum.h"


 #define CAEdgeAntialiasingMask_SETTINGS_PARAMS CAEdgeAntialiasingMask,mask,EdgeMask,edgeMask

 interface_NSString_Enum_Converters(CAEdgeAntialiasingMask_SETTINGS_PARAMS)

W myfile.m:


 // we can put this in the .m file as we are not defining a typedef, just the strings.
 #define define_CAEdgeAntialiasingMask(enum)\
 enum(kCALayerLeftEdge)\
 enum(kCALayerRightEdge)\
 enum(kCALayerBottomEdge)\
 enum(kCALayerTopEdge)



 implementation_NSString_Enum_Converters(CAEdgeAntialiasingMask_SETTINGS_PARAMS)
 0
Author: unsynchronized,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-21 01:48:01

Tutaj działa - > https://github.com/ndpiparava/ObjcEnumString

//1st Approach
#define enumString(arg) (@""#arg)

//2nd Approach

+(NSString *)secondApproach_convertEnumToString:(StudentProgressReport)status {

    char *str = calloc(sizeof(kgood)+1, sizeof(char));
    int  goodsASInteger = NSSwapInt((unsigned int)kgood);
    memcpy(str, (const void*)&goodsASInteger, sizeof(goodsASInteger));
    NSLog(@"%s", str);
    NSString *enumString = [NSString stringWithUTF8String:str];
    free(str);

    return enumString;
}

//Third Approcah to enum to string
NSString *const kNitin = @"Nitin";
NSString *const kSara = @"Sara";


typedef NS_ENUM(NSUInteger, Name) {
    NameNitin,
    NameSara,
};

+ (NSString *)thirdApproach_convertEnumToString :(Name)weekday {

    __strong NSString **pointer = (NSString **)&kNitin;
    pointer +=weekday;
    return *pointer;
}
 0
Author: Nit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-05 07:26:34

W zależności od potrzeb, możesz alternatywnie użyć dyrektyw kompilatora, aby symulować zachowanie, którego szukasz.

 #define JSON @"JSON"
 #define XML @"XML"
 #define Atom @"Atom"
 #define RSS @"RSS"

Po prostu pamiętaj o zwykłych niedociągnięciach kompilatora (nie jest bezpieczny, direct copy-paste sprawia, że plik źródłowy jest Większy)

 -2
Author: Alex Gosselin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-26 03:22:40