cra*_*aig 138 c enums typedef objective-c
假设我在.h文件中声明了一个typedef:
typedef enum {
  JSON,
  XML,
  Atom,
  RSS
} FormatType;
我想构建一个将typedef的数值转换为字符串的函数.例如,如果邮件[self toString:JSON]已发送; 它会返回'JSON'.
该函数看起来像这样:
-(NSString *) toString:(FormatType)formatType {
  //need help here
  return [];
}
顺便说一句,如果我尝试这种语法
[self toString:FormatType.JSON];
要将typedef值传递给方法,我收到一个错误.我错过了什么?
Bar*_*ark 134
这实际上是一个C问题,不是Objective-C特有的(它是C语言的超集).C中的枚举表示为整数.因此,您需要编写一个函数,该函数返回给定枚举值的字符串.有很多方法可以做到这一点.一个字符串数组,使得枚举值可以用作数组的索引或映射结构(例如a NSDictionary)将枚举值映射到字符串工作,但我发现这些方法不像函数那样清晰使转换显式(和数组方法,虽然C如果你的枚举值不是从0开始是经典的方法是危险的).像这样的东西会起作用:
- (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;
}
关于枚举值的正确语法的相关问题是您只使用值(例如JSON),而不是FormatType.JSONsytax.FormatType是一种类型,枚举值(例如JSON,XML等)是您可以分配给该类型的值.
Ada*_*eld 126
你不能轻易做到.在C和Objective-C中,枚举实际上只是美化的整数常量.您必须自己生成一个名称表(或者使用一些预处理程序滥用).例如:
// 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];
这种方法的危险在于,如果您更改了枚举,则必须记住更改名称数组.您可以通过一些预处理程序滥用来解决此问题,但这很棘手且难看.
另请注意,这假设您具有有效的枚举常量.如果你有一个来自不受信任来源的整数值,你还需要检查你的常量是否有效,例如在你的枚举中包含一个"过去最大值",或者检查它是否小于数组长度sizeof(FormatType_toString) / sizeof(FormatType_toString[0]).
Yar*_*sim 50
我的解决方案:
编辑:我在最后使用Modern Obj-C添加了更好的解决方案 
 
1. 
将名称作为键放在数组中.
确保索引是适当的枚举,并按正确的顺序(否则例外).
注意:names是一个合成为*_names*的属性;
代码没有检查编译,但我在我的应用程序中使用相同的技术.
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. 
使用Modern Obj-C,我们可以使用字典将描述绑定到枚举中的键.
订单无所谓.
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)];
}
用法(在类实例方法中):
NSLog(@"%@", [self typeDisplayName]);
小智 29
结合@AdamRosenfield的答案,@ Christoph评论和处理普通C枚举的另一个技巧我建议:
// 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]);
在最坏的情况下 - 比如你改变枚举但忘记更改名字数组 - 它将为此键返回nil.
kit*_*ter 12
在类头中定义typedef枚举:
typedef enum {
    IngredientType_text  = 0,
    IngredientType_audio = 1,
    IngredientType_video = 2,
    IngredientType_image = 3
} IngredientType;
在类中编写这样的方法:
+ (NSString*)typeStringForType:(IngredientType)_type {
   NSString *key = [NSString stringWithFormat:@"IngredientType_%i", _type];
   return NSLocalizedString(key, nil);
}
在Localizable.strings文件中有字符串:
/* IngredientType_text */
"IngredientType_0" = "Text";
/* IngredientType_audio */
"IngredientType_1" = "Audio";
/* IngredientType_video */
"IngredientType_2" = "Video";
/* IngredientType_image */
"IngredientType_3" = "Image";
小智 11
我会使用编译器的#string标记(以及宏来使它更紧凑):
#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
}
我喜欢#define这样做的方式:
//将它放在@interface块之外的.h文件中
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];
}
来源(来源不再可用)
我把这个页面上的所有解决方案混合在一起创建我的,它是一种面向对象的枚举扩展或其他东西.
事实上,如果你需要的不仅仅是常量(即整数),你可能需要一个模型对象(我们都在谈论MVC,对吧?)
在使用它之前问问自己这个问题,我是对的,不是吗,实际上,你需要一个真正的模型对象,从webservice,plist,SQLite数据库或CoreData初始化?
无论如何这里是代码(MPI代表"我的项目缩写",每个人都使用这个或他们的名字,似乎):
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
而且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
小智 5
另一种方案:
typedef enum BollettinoMavRavTypes {
    AMZCartServiceOperationCreate,
    AMZCartServiceOperationAdd,
    AMZCartServiceOperationGet,
    AMZCartServiceOperationModify
} AMZCartServiceOperation;
#define AMZCartServiceOperationValue(operation) [[[NSArray alloc] initWithObjects: @"CartCreate", @"CartAdd", @"CartGet", @"CartModify", nil] objectAtIndex: operation];
在您的方法中,您可以使用:
NSString *operationCheck = AMZCartServiceOperationValue(operation);