2013-04-04 46 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. 您可以將其他屬性添加到您的枚舉值(你確定你不想使用類?)