cra*_*aig 138 c enums typedef objective-c
假设我在.h文件中声明了一个typedef:
typedef enum {
JSON,
XML,
Atom,
RSS
} FormatType;
Run Code Online (Sandbox Code Playgroud)
我想构建一个将typedef的数值转换为字符串的函数.例如,如果邮件[self toString:JSON]
已发送; 它会返回'JSON'.
该函数看起来像这样:
-(NSString *) toString:(FormatType)formatType {
//need help here
return [];
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,如果我尝试这种语法
[self toString:FormatType.JSON];
Run Code Online (Sandbox Code Playgroud)
要将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;
}
Run Code Online (Sandbox Code Playgroud)
关于枚举值的正确语法的相关问题是您只使用值(例如JSON
),而不是FormatType.JSON
sytax.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];
Run Code Online (Sandbox Code Playgroud)
这种方法的危险在于,如果您更改了枚举,则必须记住更改名称数组.您可以通过一些预处理程序滥用来解决此问题,但这很棘手且难看.
另请注意,这假设您具有有效的枚举常量.如果你有一个来自不受信任来源的整数值,你还需要检查你的常量是否有效,例如在你的枚举中包含一个"过去最大值",或者检查它是否小于数组长度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];
}
Run Code Online (Sandbox Code Playgroud)
//
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)];
}
Run Code Online (Sandbox Code Playgroud)
用法(在类实例方法中):
NSLog(@"%@", [self typeDisplayName]);
Run Code Online (Sandbox Code Playgroud)
小智 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]);
Run Code Online (Sandbox Code Playgroud)
在最坏的情况下 - 比如你改变枚举但忘记更改名字数组 - 它将为此键返回nil.
kit*_*ter 12
在类头中定义typedef枚举:
typedef enum {
IngredientType_text = 0,
IngredientType_audio = 1,
IngredientType_video = 2,
IngredientType_image = 3
} IngredientType;
Run Code Online (Sandbox Code Playgroud)
在类中编写这样的方法:
+ (NSString*)typeStringForType:(IngredientType)_type {
NSString *key = [NSString stringWithFormat:@"IngredientType_%i", _type];
return NSLocalizedString(key, nil);
}
Run Code Online (Sandbox Code Playgroud)
在Localizable.strings文件中有字符串:
/* IngredientType_text */
"IngredientType_0" = "Text";
/* IngredientType_audio */
"IngredientType_1" = "Audio";
/* IngredientType_video */
"IngredientType_2" = "Video";
/* IngredientType_image */
"IngredientType_3" = "Image";
Run Code Online (Sandbox Code Playgroud)
小智 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
}
Run Code Online (Sandbox Code Playgroud)
我喜欢#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];
}
Run Code Online (Sandbox Code Playgroud)
来源(来源不再可用)
我把这个页面上的所有解决方案混合在一起创建我的,它是一种面向对象的枚举扩展或其他东西.
事实上,如果你需要的不仅仅是常量(即整数),你可能需要一个模型对象(我们都在谈论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
Run Code Online (Sandbox Code Playgroud)
而且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
Run Code Online (Sandbox Code Playgroud)
小智 5
另一种方案:
typedef enum BollettinoMavRavTypes {
AMZCartServiceOperationCreate,
AMZCartServiceOperationAdd,
AMZCartServiceOperationGet,
AMZCartServiceOperationModify
} AMZCartServiceOperation;
#define AMZCartServiceOperationValue(operation) [[[NSArray alloc] initWithObjects: @"CartCreate", @"CartAdd", @"CartGet", @"CartModify", nil] objectAtIndex: operation];
Run Code Online (Sandbox Code Playgroud)
在您的方法中,您可以使用:
NSString *operationCheck = AMZCartServiceOperationValue(operation);
Run Code Online (Sandbox Code Playgroud)