我正在挖掘枚举objc对象的方法,比如NSString,我记得在Xcode4 +版本中有一个新功能,它提供了一种新的枚举方式,但不清楚。有人知道吗?
答案 0 :(得分:34)
这是我上面提到的新功能:
typedef enum Language : NSUInteger{
ObjectiveC,
Java,
Ruby,
Python,
Erlang
}Language;
这只是Xcode 4.4中enum的一种新语法,但我认为我们可以将“NSUInteger”交换为“NSString”是非常愚蠢的。
所以这就是我找到的方式:
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。第二个示例代码的原作者为枚举处理创建了一个类别。只是添加到您自己的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
答案 1 :(得分:23)
使用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"
};
然后你就可以这样使用:
NSString *status = AMPlayerState.ready;
易于使用,易读。 如果有人使用上述方法的优点/缺点更新/编辑答案,那就太好了。
答案 2 :(得分:9)
这将由编译器验证,因此您不会意外混淆索引。
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]
答案 3 :(得分:8)
最近的投票引起了我的注意,我想补充一点,enum
现在很容易与String
合作:
enum HTTPMethod: String {
case GET, POST, PUT
}
HTTPMethod.GET.rawValue == "GET" // it's true
#define HLCSRestMethodGet @"GET"
#define HLCSRestMethodPost @"POST"
#define HLCSRestMethodPut @"PUT"
#define HLCSRestMethodDelete @"DELETE"
typedef NSString* HLCSRestMethod;
我知道这不是OP所要求的,但编写实际代码来实现枚举似乎对我来说太过分了。我会将enum视为一种语言特性(来自C),如果我必须编写代码,我会想出一些比枚举更好的类。
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
}
}
答案 4 :(得分:1)
我认为您正在寻找内联数组函数。例如
@[@"stringone",@"stringtwo",@"stringthree"];
如果没有,我不确定你可以枚举对象。
但是你可以有一个静态的字符串数组,并且在索引处有枚举引用对象。
答案 5 :(得分:0)
在enum Values to NSString (iOS)查看我的回答 - 我相信这可能是解决此问题的更优雅的方法。
答案 6 :(得分:0)
苹果文档推荐的方法:
您可以使用NS_TYPED_ENUM将常量与指定的原始值类型分组。将NS_TYPED_ENUM用于在逻辑上不能在Swift扩展中添加值的常量集,并将NS_TYPED_EXTENSIBLE_ENUM用于可在扩展中扩展的常量集。 Apple docs
typedef NSString *MyEnum NS_TYPED_ENUM;
extern MyEnum const MyEnumFirstValue;
extern MyEnum const MyEnumSecondValue;
extern MyEnum const MyEnumThirdValue;
.h文件中的。在.m文件中定义您的字符串
MyEnum const MyEnumFirstValue = @"MyEnumFirstValue"
MyEnum const MyEnumSecondValue = @"MyEnumSecondValue";
MyEnum const MyEnumThirdValue = @"MyEnumThirdValue";
在Objective-C中都能按预期工作
- (void)methodWithMyEnum:(MyEnum)myEnum { }
和Swift
func method(_ myEnum: MyEnum) { }
答案 7 :(得分:0)
我就是这样做的,虽然它并不完美。我觉得切换机制可以改进……对哈希冲突抵抗也不乐观,不知道苹果在引擎盖下使用了什么。
#define ElementProperty NSString *
#define __ElementPropertiesList @[@"backgroundColor", @"scale", @"alpha"]
#define epBackgroundColor __ElementPropertiesList[0]
#define epScale __ElementPropertiesList[1]
#define epAlpha __ElementPropertiesList[2]
#define switchElementProperty(__ep) switch(__ep.hash)
#define caseElementProperty(__ep) case(__ep.hash)
-(void)setValue:(id)value forElementProperty:(ElementProperty)ep;
[self setValue:@(1.5) forElementProperty:epScale];
//Compiler unfortunately won't warn you if you are missing a case
switchElementProperty(myProperty) {
caseElementProperty(epBackgroundColor):
NSLog(@"bg");
break;
caseElementProperty(epScale):
NSLog(@"s");
break;
caseElementProperty(epAlpha):
NSLog(@"a");
break;
}