I combined several approaches here. I like the idea of the preprocessor and the indexed list.
There's no extra dynamic allocation, and because of the inlining the compiler might be able to optimize the lookup.
typedef NS_ENUM(NSUInteger, FormatType) { FormatTypeJSON = 0, FormatTypeXML, FormatTypeAtom, FormatTypeRSS, FormatTypeCount };
NS_INLINE NSString *FormatTypeToString(FormatType t) {
if (t >= FormatTypeCount)
return nil;
#define FormatTypeMapping(value) [value] = @#value
NSString *table[FormatTypeCount] = {FormatTypeMapping(FormatTypeJSON),
FormatTypeMapping(FormatTypeXML),
FormatTypeMapping(FormatTypeAtom),
FormatTypeMapping(FormatTypeRSS)};
#undef FormatTypeMapping
return table[t];
}