2013-04-04 69 views
3

我正在开发带有最新SDK的iOS应用程序。如何在Objective-C中迭代throw typedef枚举?

我有这样的枚举:

typedef enum BoxTypeValues { 
    Speed, 
    FPS, 
    Altitude, 
    Location, 
    Accuracy 
} BoxType; 

我想扔迭代其所有值,并将其转换为NSString

我做这种方式,但它是非常硬编码:

+ (NSArray*)BoxTypeValues 
{ 
    return [NSArray arrayWithObjects:@"Speed", @"FPS", @"Altitude", @"Location", 
      @"Accuracy", nil]; 
} 

+ (NSString*)BoxTypeToString:(BoxType)aType 
{ 
    NSString* result = nil; 

    switch (aType) 
    { 
     case Speed: 
      result = @"Speed"; 
      break; 
     case FPS: 
      result = @"FPS"; 
      break; 
     case Altitude: 
      result = @"Altitude"; 
      break; 
     case Location: 
      result = @"Location"; 
      break; 
     case Accuracy: 
      result = @"Accuracy"; 
      break; 

     default: 
      break; 
    } 
    return result; 
} 

有什么建议?

+0

你逝去的同名并将其存储在字符串?有什么需要这样做? – 2013-04-04 10:03:40

+0

对不起,但我不明白你的问题。 – VansFannel 2013-04-04 10:07:19

+0

您正在切换FPS并返回FPS ,,,,,所以不需要使用开关盒,只需返回字符串即可。不是吗? – 2013-04-04 10:10:00

回答

6

将枚举值转换为字符串是宏可以帮助很多的罕见情况之一。例如:

- (NSString*)BoxTypeToString:(BoxType)aType 
{ 
#define CASE(VALUE) case (VALUE): return @(#VALUE) 
    switch (aType) { 
      CASE(Speed); 
      CASE(FPS); 
      CASE(Altitude); 
      CASE(Location); 
      CASE(Accuracy); 

     default: 
      // should not get here 
      assert(0); 
      break; 
    } 
#undef CASE 
    return nil; 
} 

BoxTypeValues方法会再看看这样的:

- (NSArray*)BoxTypeStringValues 
{ 
    return @[ 
     [self BoxTypeToString:Speed], 
     [self BoxTypeToString:FPS], 
     [self BoxTypeToString:Altitude], 
     [self BoxTypeToString:Location], 
     [self BoxTypeToString:Accuracy] 
     ]; 
} 

这将继续甚至重构操作重命名枚举值后很好地工作。您可能需要给CASE宏指定某种独特的前缀以避免与其他代码发生冲突。

至于枚举枚举值,你运气不好,除非你可以依赖的价值是顺序和使用标准的循环(如其他人所建议的)。

+0

这太棒了。 – yinkou 2013-04-04 10:10:49

+0

“@(#VALUE)”中的hashtag是做什么的? – 2013-05-28 14:58:26

+0

它将参数字符串化,将其变成一个C文字,然后将其装入@()内的NSString中。 – 2013-05-28 18:34:52

2
+ (NSString*)BoxTypeToString:(BoxType)aType{ 
    return [BoxTypeValues objectAtIndex:aType]; 
} 

只需修改您的方法,无需使用开关盒。

+0

+1正是我想在评论中说的。 – 2013-04-04 10:10:27

+0

,如果您仍然不想创建硬编码数组,则使用Dictionary而不是枚举 – 2013-04-04 10:13:47

0

如果您控制枚举并确保它是连续的,那么您可以执行以下操作 - 但显然您现在必须做些事情来保持最新。

typedef NS_ENUM(NSInteger, BoxType) { 
    Speed, 
    FPS, 
    Altitude, 
    Location, 
    Accuracy 
}; 

NSString * BoxTypeToString(BoxType boxType) 
{ 
    static NSString *types[] = { @"Speed", @"FPS", @"Altitude", @"Location", @"Accuracy" }; 
    return types[boxType]; 
} 

NB

我做了这个一个单独的C函数,因为我真的不能想象许多情况下,让一个很好的理由,一类负责懂得如何枚举转换成字符串:/

1

我多次遇到此问题。每个看到Java枚举的人都想在Obj-C中使用这个功能。

其中一个解决方案是使用类而不是枚举。如果你想去enums,有一个很好的预处理器技术,称为X-Macros

让我们先来定义的值:

#define BOX_TYPE_DEFINITIONS \ 
    BOX_TYPE_DEFINITION(Invalid, = 0) \ 
    BOX_TYPE_DEFINITION(Speed,) \ 
    BOX_TYPE_DEFINITION(FPS,) \ 
    BOX_TYPE_DEFINITION(Altitude,) \ 
    BOX_TYPE_DEFINITION(Location,) \ 
    BOX_TYPE_DEFINITION(Accuracy,) 

现在枚举

#define BOX_TYPE_DEFINITION(name, intValue) name intValue, 

typedef enum { 
    BOX_TYPE_DEFINITIONS 
} BoxType; 

#undef BOX_TYPE_DEFINITION 

和 “串” 功能

#define BOX_TYPE_DEFINITION(name, intValue) [name] = @#name, 

NSString* BoxTypeStringTable[] = { 
    BOX_TYPE_DEFINITIONS 
}; 

#undef BOX_TYPE_DEFINITION 

#define NUM_BOX_TYPES sizeof(BoxTypeStringTable)/sizeof(NSString*) 

NSString* NSStringFromBoxType(BoxType type) { 
    return BoxTypeStringTable[type]; 
} 

这种技术是3个原因,

很强大
  1. 如果要添加/删除值,只需在一个地方执行即可。
  2. 您将值列表作为宏使用,您几乎可以生成任何涉及所有值的代码。
  3. 您可以将其他属性添加到您的枚举值(你确定你不想使用类?)