枚举值到 NSString (iOS)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6331762/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
enum Values to NSString (iOS)
提问by Ohad Regev
I have an enum holding several values:
我有一个包含多个值的枚举:
enum {value1, value2, value3} myValue;
枚举 {value1, value2, value3} myValue;
In a certain point in my app, I wish to check which value of the enum is now active. I'm using NSLog but I'm not clear on how to display the current value of the enum (value1/valu2/valu3/etc...) as a NSString for the NSLog.
在我的应用程序中的某个点,我希望检查枚举的哪个值现在处于活动状态。我正在使用 NSLog,但我不清楚如何将枚举的当前值(value1/value2/value3/etc...)显示为 NSLog 的 NSString。
Anyone?
任何人?
采纳答案by badMonkey
This is answered here: a few suggestions on implementation
这是在这里回答:关于实施的一些建议
The bottom line is Objective-C
is using a regular, old C
enum
, which is just a glorified set of integers.
底线Objective-C
是使用常规的 old C
enum
,它只是一组美化的整数。
Given an enum
like this:
鉴于enum
这样的:
typedef enum { a, b, c } FirstThreeAlpha;
Your method would look like this:
您的方法如下所示:
- (NSString*) convertToString:(FirstThreeAlpha) whichAlpha {
NSString *result = nil;
switch(whichAlpha) {
case a:
result = @"a";
break;
case b:
result = @"b";
break;
case c:
result = @"c";
break;
default:
result = @"unknown";
}
return result;
}
回答by Mark Longmire
I didn't like putting the enum on the heap, without providing a heap function for translation. Here's what I came up with:
我不喜欢将枚举放在堆上,而不提供用于翻译的堆函数。这是我想出的:
typedef enum {value1, value2, value3} myValue;
#define myValueString(enum) [@[@"value1",@"value2",@"value3"] objectAtIndex:enum]
This keeps the enum and string declarations close together for easy updating when needed.
这使枚举和字符串声明紧密结合在一起,以便在需要时轻松更新。
Now, anywhere in the code, you can use the enum/macro like this:
现在,在代码的任何地方,您都可以像这样使用枚举/宏:
myValue aVal = value2;
NSLog(@"The enum value is '%@'.", myValueString(aVal));
outputs: The enum value is 'value2'.
To guarantee the element indexes, you can always explicitly declare the start(or all) enum values.
为了保证元素索引,您始终可以显式声明开始(或所有)枚举值。
enum {value1=0, value2=1, value3=2};
回答by Han-Jong Ko
I will introduce is the way I use, and it looks better than previous answer.(I thinks)
我将介绍的是我使用的方式,它看起来比以前的答案更好。(我认为)
I would like to illustrate with UIImageOrientationfor easy understanding.
为了便于理解,我想用UIImageOrientation来说明。
typedef enum {
UIImageOrientationUp = 0, // default orientation, set to 0 so that it always starts from 0
UIImageOrientationDown, // 180 deg rotation
UIImageOrientationLeft, // 90 deg CCW
UIImageOrientationRight, // 90 deg CW
UIImageOrientationUpMirrored, // as above but image mirrored along other axis. horizontal flip
UIImageOrientationDownMirrored, // horizontal flip
UIImageOrientationLeftMirrored, // vertical flip
UIImageOrientationRightMirrored, // vertical flip
} UIImageOrientation;
create a method like:
创建一个方法,如:
NSString *stringWithUIImageOrientation(UIImageOrientation input) {
NSArray *arr = @[
@"UIImageOrientationUp", // default orientation
@"UIImageOrientationDown", // 180 deg rotation
@"UIImageOrientationLeft", // 90 deg CCW
@"UIImageOrientationRight", // 90 deg CW
@"UIImageOrientationUpMirrored", // as above but image mirrored along other axis. horizontal flip
@"UIImageOrientationDownMirrored", // horizontal flip
@"UIImageOrientationLeftMirrored", // vertical flip
@"UIImageOrientationRightMirrored", // vertical flip
];
return (NSString *)[arr objectAtIndex:input];
}
All you have to do is :
您所要做的就是:
name your function.
copy contents of enum and paste that between NSArray *arr = @[and ]; return (NSString *)[arr objectAtIndex:input];
put some @ , " , and comma
PROFIT!!!!
命名你的函数。
复制枚举的内容并将其粘贴到NSArray *arr = @[和 ] 之间;return (NSString *)[arr objectAtIndex:input];
放一些 @ 、 " 和逗号
利润!!!!
回答by Geri Borbás
This will be validated by compiler, so you won't mix up indices accidentally.
这将由编译器验证,因此您不会意外混淆索引。
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]
回答by ajmccall
I found this website(from which the example below is taken) which provides an elegant solution to this problem. The original posting though comes from this StackOverflow answer.
我找到了这个网站(下面的例子来自该网站),它为这个问题提供了一个优雅的解决方案。最初的帖子虽然来自这个StackOverflow answer。
// 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;
}
回答by Leszek Szary
In some cases when you need to convert enum -> NSString and NSString -> enum it might be simpler to use a typedef and #define (or const NSStrings) instead of enum:
在某些情况下,当您需要转换 enum -> NSString 和 NSString -> enum 时,使用 typedef 和 #define(或 const NSStrings)而不是 enum 可能更简单:
typedef NSString * ImageType;
#define ImageTypeJpg @"JPG"
#define ImageTypePng @"PNG"
#define ImageTypeGif @"GIF"
and then just operate with "named" strings as with any other NSString:
然后像任何其他 NSString 一样使用“命名”字符串:
@interface MyData : NSObject
@property (copy, nonatomic) ImageType imageType;
@end
@implementation MyData
- (void)doSomething {
//...
self.imageType = ImageTypePng;
//...
if ([self.imageType isEqualToString:ImageTypeJpg]) {
//...
}
}
@end
回答by JVillella
If I can offer another solution that has the added benefit of type checking, warnings if you are missing an enum value in your conversion, readability, and brevity.
如果我可以提供另一种具有类型检查额外好处的解决方案,如果您在转换、可读性和简洁性中缺少枚举值,则会发出警告。
For your given example: typedef enum { value1, value2, value3 } myValue;
you can do this:
对于您给定的示例:typedef enum { value1, value2, value3 } myValue;
您可以这样做:
NSString *NSStringFromMyValue(myValue type) {
const char* c_str = 0;
#define PROCESS_VAL(p) case(p): c_str = #p; break;
switch(type) {
PROCESS_VAL(value1);
PROCESS_VAL(value2);
PROCESS_VAL(value3);
}
#undef PROCESS_VAL
return [NSString stringWithCString:c_str encoding:NSASCIIStringEncoding];
}
As a side note. It is a better approach to declare your enums as so:
作为旁注。将您的枚举声明如下是一种更好的方法:
typedef NS_ENUM(NSInteger, MyValue) {
Value1 = 0,
Value2,
Value3
}
With this you get type-safety (NSInteger
in this case), you set the expected enum offset (= 0
).
有了这个,您就可以获得类型安全(NSInteger
在这种情况下),您可以设置预期的枚举偏移量 ( = 0
)。
回答by BooTooMany
The solution below uses the preprocessor's stringize operator, allowing for a more elegant solution. It lets you define the enum terms in just one place for greater resilience against typos.
下面的解决方案使用预处理器的 stringize 运算符,从而提供更优雅的解决方案。它让您可以在一处定义枚举术语,以提高对错别字的恢复能力。
First, define your enum in the following way.
首先,按以下方式定义您的枚举。
#define ENUM_TABLE \
X(ENUM_ONE), \
X(ENUM_TWO) \
#define X(a) a
typedef enum Foo {
ENUM_TABLE
} MyFooEnum;
#undef X
#define X(a) @#a
NSString * const enumAsString[] = {
ENUM_TABLE
};
#undef X
Now, use it in the following way:
现在,按以下方式使用它:
// Usage
MyFooEnum t = ENUM_ONE;
NSLog(@"Enum test - t is: %@", enumAsString[t]);
t = ENUM_TWO;
NSLog(@"Enum test - t is now: %@", enumAsString[t]);
which outputs:
输出:
2014-10-22 13:36:21.344 FooProg[367:60b] Enum test - t is: ENUM_ONE
2014-10-22 13:36:21.344 FooProg[367:60b] Enum test - t is now: ENUM_TWO
@pixel's answer pointed me in the right direction.
@pixel 的回答为我指明了正确的方向。
回答by pixel
You could use X macros - they are perfect for this.
您可以使用 X 宏 - 它们非常适合于此。
Benefits1. the relationship between the actual enum value and the string value is in one place. 2. you can use regular switch statements later in your code.
好处1.实际枚举值和字符串值的关系在一处。2. 您可以稍后在代码中使用常规的 switch 语句。
Detriment1. The initial setup code is a bit obtuse, and uses fun macros.
弊端1. 初始设置代码有点迟钝,并且使用了有趣的宏。
The code
编码
#define X(a, b, c) a b,
enum ZZObjectType {
ZZOBJECTTYPE_TABLE
};
typedef NSUInteger TPObjectType;
#undef X
#define XXOBJECTTYPE_TABLE \
X(ZZObjectTypeZero, = 0, "ZZObjectTypeZero") \
X(ZZObjectTypeOne, = 1, "ZZObjectTypeOne") \
X(ZZObjectTypeTwo, = 2, "ZZObjectTypeTwo") \
X(ZZObjectTypeThree, = 3, "ZZObjectTypeThree") \
+ (NSString*)nameForObjectType:(ZZObjectType)objectType {
#define X(a, b, c) @c, [NSNumber numberWithInteger:a],
NSDictionary *returnValue = [NSDictionary dictionaryWithObjectsAndKeys:ZZOBJECTTYPE_TABLE nil];
#undef X
return [returnValue objectForKey:[NSNumber numberWithInteger:objectType]];
}
+ (ZZObjectType)objectTypeForName:(NSString *)objectTypeString {
#define X(a, b, c) [NSNumber numberWithInteger:a], @c,
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:ZZOBJECTSOURCE_TABLE nil];
#undef X
NSUInteger value = [(NSNumber *)[dictionary objectForKey:objectTypeString] intValue];
return (ZZObjectType)value;
}
Now you can do:
现在你可以这样做:
NSString *someString = @"ZZObjectTypeTwo"
ZZObjectType objectType = [[XXObject objectTypeForName:someString] intValue];
switch (objectType) {
case ZZObjectTypeZero:
//
break;
case ZZObjectTypeOne:
//
break;
case ZZObjectTypeTwo:
//
break;
}
This pattern has been around since the 1960's (no kidding!): http://en.wikipedia.org/wiki/X_Macro
这种模式自 1960 年代以来一直存在(不是开玩笑!):http: //en.wikipedia.org/wiki/X_Macro
回答by eGanges
Here is a plug-and-play solution that you can extend with a simple copy and paste of your EXISTING definitions.
这是一个即插即用的解决方案,您可以通过简单复制和粘贴现有定义进行扩展。
I hope you all find it useful, as I have found useful so many other StackOverflow solutions.
我希望你们都觉得它很有用,因为我发现很多其他 StackOverflow 解决方案都很有用。
- (NSString*) enumItemNameForPrefix:(NSString*)enumPrefix item:(int)enumItem {
NSString* enumList = nil;
if ([enumPrefix isEqualToString:@"[Add Your Enum Name Here"]) {
// Instructions:
// 1) leave all code as is (it's good reference and won't conflict)
// 2) add your own enums below as follows:
// 2.1) duplicate the LAST else block below and add as many enums as you like
// 2.2) Copy then Paste your list, including carraige returns
// 2.3) add a back slash at the end of each line to concatenate the broken string
// 3) your are done.
}
else if ([enumPrefix isEqualToString:@"ExampleNonExplicitType"]) {
enumList = @" \
ExampleNonExplicitTypeNEItemName1, \
ExampleNonExplicitTypeNEItemName2, \
ExampleNonExplicitTypeNEItemName3 \
";
}
else if ([enumPrefix isEqualToString:@"ExampleExplicitAssignsType"]) {
enumList = @" \
ExampleExplicitAssignsTypeEAItemName1 = 1, \
ExampleExplicitAssignsTypeEAItemName2 = 2, \
ExampleExplicitAssignsTypeEAItemName3 = 4 \
";
}
else if ([enumPrefix isEqualToString:@"[Duplicate and Add Your Enum Name Here #1"]) {
// Instructions:
// 1) duplicate this else block and add as many enums as you like
// 2) Paste your list, including carraige returns
// 3) add a back slash at the end of each line to continue/concatenate the broken string
enumList = @" \
[Replace only this line: Paste your Enum Definition List Here] \
";
}
// parse it
int implicitIndex = 0;
NSString* itemKey = nil;
NSString* itemValue = nil;
NSArray* enumArray = [enumList componentsSeparatedByString:@","];
NSMutableDictionary* enumDict = [[[NSMutableDictionary alloc] initWithCapacity:enumArray.count] autorelease];
for (NSString* itemPair in enumArray) {
NSArray* itemPairArray = [itemPair componentsSeparatedByString:@"="];
itemValue = [[itemPairArray objectAtIndex:0] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
itemKey = [NSString stringWithFormat:@"%d", implicitIndex];
if (itemPairArray.count > 1)
itemKey = [[itemPairArray lastObject] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[enumDict setValue:itemValue forKey:itemKey];
implicitIndex++;
}
// return value with or without prefix
NSString* withPrefix = [enumDict valueForKey:[NSString stringWithFormat:@"%d", enumItem]];
NSString* withoutPrefix = [withPrefix stringByReplacingOccurrencesOfString:enumPrefix withString:@""];
NSString* outValue = (0 ? withPrefix : withoutPrefix);
if (0) NSLog(@"enum:%@ item:%d retVal:%@ dict:%@", enumPrefix, enumItem, outValue, enumDict);
return outValue;
}
Here are the example declarations:
以下是示例声明:
typedef enum _type1 {
ExampleNonExplicitTypeNEItemName1,
ExampleNonExplicitTypeNEItemName2,
ExampleNonExplicitTypeNEItemName3
} ExampleNonExplicitType;
typedef enum _type2 {
ExampleExplicitAssignsTypeEAItemName1 = 1,
ExampleExplicitAssignsTypeEAItemName2 = 2,
ExampleExplicitAssignsTypeEAItemName3 = 4
} ExampleExplicitAssignsType;
Here is an example call:
下面是一个例子电话:
NSLog(@"EXAMPLE: type1:%@ type2:%@ ", [self enumItemNameForPrefix:@"ExampleNonExplicitType" item:ExampleNonExplicitTypeNEItemName2], [self enumItemNameForPrefix:@"ExampleExplicitAssignsType" item:ExampleExplicitAssignsTypeEAItemName3]);
Enjoy! ;-)
享受!;-)