ios 枚举 NSString 的最佳方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13171907/
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
Best way to enum NSString
提问by kimimaro
Im digging for ways to enum objc object such as NSString, I remember there a new feature in a version of Xcode4+ which offering a new way to enum , but not clearly. Anyone know that?
我正在寻找枚举 objc 对象(例如 NSString)的方法,我记得 Xcode4+ 版本中有一个新功能,它提供了一种新的 enum 方法,但不清楚。有人知道吗?
回答by kimimaro
OK, I answered myself. Guess I make a mistake.
好的,我自己回答。猜我犯了一个错误。
This is the new feature I mentioned above:
这是我上面提到的新功能:
typedef enum Language : NSUInteger{
ObjectiveC,
Java,
Ruby,
Python,
Erlang
}Language;
It's just a new syntax for enum in Xcode 4.4, but I'm so foolish to think we can exchange "NSUInteger" to "NSString".
这只是 Xcode 4.4 中枚举的新语法,但我很愚蠢地认为我们可以将“NSUInteger”交换为“NSString”。
So here is the way I found that works:
所以这是我发现有效的方式:
http://longweekendmobile.com/2010/12/01/not-so-nasty-enums-in-objective-c/
http://longweekendmobile.com/2010/12/01/not-so-nasty-enums-in-objective-c/
// 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;
}
FYI. The original author of the second example code created a category for enum handling. Just the thing for adding to your very own NSArray class definition.
供参考。第二个示例代码的原作者创建了一个用于枚举处理的类别。只是添加到您自己的 NSArray 类定义中的事情。
@interface NSArray (EnumExtensions)
- (NSString*) stringWithEnum: (NSUInteger) enumVal;
- (NSUInteger) enumFromString: (NSString*) strVal default: (NSUInteger) def;
- (NSUInteger) enumFromString: (NSString*) strVal;
@end
@implementation NSArray (EnumExtensions)
- (NSString*) stringWithEnum: (NSUInteger) enumVal
{
return [self objectAtIndex:enumVal];
}
- (NSUInteger) enumFromString: (NSString*) strVal default: (NSUInteger) def
{
NSUInteger n = [self indexOfObject:strVal];
if(n == NSNotFound) n = def;
return n;
}
- (NSUInteger) enumFromString: (NSString*) strVal
{
return [self enumFromString:strVal default:0];
}
@end
回答by Injectios
Alternative way to use struct:
使用结构的替代方法:
extern const struct AMPlayerStateReadable
{
__unsafe_unretained NSString *ready;
__unsafe_unretained NSString *completed;
__unsafe_unretained NSString *playing;
__unsafe_unretained NSString *paused;
__unsafe_unretained NSString *broken;
} AMPlayerState;
const struct AMPlayerStateReadable AMPlayerState =
{
.ready = @"READY",
.completed = @"COMPLETE",
.playing = @"PLAYING",
.paused = @"PAUSED",
.broken = @"BROKEN"
};
Then you can use like this:
然后你可以像这样使用:
NSString *status = AMPlayerState.ready;
Easy to use, readable. Would be nice if someone update/edit answer with advantages/disadvantages of approach above.
使用方便,可读性强。如果有人使用上述方法的优点/缺点更新/编辑答案,那就太好了。
回答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 superarts.org
Update in 2017
2017年更新
Recent down votes drew me attention, and I'd like to add that enum
is really easy to work with String
now:
最近的反对票引起了我的注意,我想补充一点,enum
现在很容易使用String
:
enum HTTPMethod: String {
case GET, POST, PUT
}
HTTPMethod.GET.rawValue == "GET" // it's true
Original AnswerUnfortunately I ended up using:
原始答案不幸的是,我最终使用了:
#define HLCSRestMethodGet @"GET"
#define HLCSRestMethodPost @"POST"
#define HLCSRestMethodPut @"PUT"
#define HLCSRestMethodDelete @"DELETE"
typedef NSString* HLCSRestMethod;
I know this is not what OP asked, but writing actual code to implement enum seems to be an overkill to me. I would consider enum as a language feature (from C) and if I have to write code, I would come up with some better classes that does more than enum does.
我知道这不是 OP 所要求的,但是编写实际代码来实现枚举对我来说似乎有点矫枉过正。我会将 enum 视为一种语言特性(来自 C),如果我必须编写代码,我会想出一些比 enum 做得更好的类。
Update
更新
Swift version seems to be prettier, although the performance can never be as good.
Swift 版本似乎更漂亮,尽管性能永远不会那么好。
struct LRest {
enum HTTPMethod: String {
case Get = "GET"
case Put = "PUT"
case Post = "POST"
case Delete = "DELETE"
}
struct method {
static let get = HTTPMethod.Get
static let put = HTTPMethod.Put
static let post = HTTPMethod.Post
static let delete = HTTPMethod.Delete
}
}
}
回答by Joakim
Recommended way from apple docs:
来自苹果文档的推荐方式:
You use the NS_TYPED_ENUM to group constants with a raw value type that you specify. Use NS_TYPED_ENUM for sets of constants that can't logically have values added in a Swift extension, and use NS_TYPED_EXTENSIBLE_ENUM for sets of constants that can be expanded in an extension. Apple docs
您可以使用 NS_TYPED_ENUM 将具有您指定的原始值类型的常量分组。将 NS_TYPED_ENUM 用于逻辑上不能在 Swift 扩展中添加值的常量集,并使用 NS_TYPED_EXTENSIBLE_ENUM 用于可以在扩展中扩展的常量集。 苹果文档
typedef NSString *MyEnum NS_TYPED_ENUM;
extern MyEnum const MyEnumFirstValue;
extern MyEnum const MyEnumSecondValue;
extern MyEnum const MyEnumThirdValue;
in the .h file. Define your strings in the .m file
在 .h 文件中。在 .m 文件中定义你的字符串
MyEnum const MyEnumFirstValue = @"MyEnumFirstValue"
MyEnum const MyEnumSecondValue = @"MyEnumSecondValue";
MyEnum const MyEnumThirdValue = @"MyEnumThirdValue";
Works as expected in both Objective-C
在 Objective-C 中按预期工作
- (void)methodWithMyEnum:(MyEnum)myEnum { }
and Swift
和斯威夫特
func method(_ myEnum: MyEnum) { }
回答by Bergasms
I think you are looking for the inline array function. eg
我认为您正在寻找内联数组函数。例如
@[@"stringone",@"stringtwo",@"stringthree"];
if not, i'm not sure you can enum objects.
如果没有,我不确定您是否可以枚举对象。
you could however have a static array of strings and have the enum reference object at index.
但是,您可以拥有一个静态字符串数组,并在索引处拥有枚举引用对象。
回答by BooTooMany
See my answer at enum Values to NSString (iOS)- I believe that might be a more elegant solution to this issue.
请参阅我在enum Values to NSString (iOS) 中的回答- 我相信这可能是解决此问题的更优雅的解决方案。