枚举NSString的最佳方法

kim*_*aro 17 xcode enums ios

我正在挖掘枚举objc对象的方法,比如NSString,我记得在Xcode4 +版本中有一个新功能,它提供了一种新的枚举方式,但不清楚.有人知道吗?

kim*_*aro 34

好的,我回答了自己.我猜错了.

这是我上面提到的新功能:

typedef enum Language : NSUInteger{
     ObjectiveC,
     Java, 
     Ruby, 
     Python, 
    Erlang 
}Language;
Run Code Online (Sandbox Code Playgroud)

它只是Xcode 4.4中枚举的一种新语法,但我认为我们可以将"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;
}
Run Code Online (Sandbox Code Playgroud)

仅供参考.第二个示例代码的原作者为枚举处理创建了一个类别.只是添加到您自己的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
Run Code Online (Sandbox Code Playgroud)


Inj*_*ios 24

使用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"
};
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样使用:

NSString *status = AMPlayerState.ready;
Run Code Online (Sandbox Code Playgroud)

易于使用,易读.如果有人使用上述方法的优点/缺点更新/编辑答案,那将会很好.


Joa*_*kim 10

来自苹果文档的推荐方式:

您可以使用 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;
Run Code Online (Sandbox Code Playgroud)

在 .h 文件中。在 .m 文件中定义你的字符串

MyEnum const MyEnumFirstValue = @"MyEnumFirstValue"
MyEnum const MyEnumSecondValue = @"MyEnumSecondValue";
MyEnum const MyEnumThirdValue = @"MyEnumThirdValue";
Run Code Online (Sandbox Code Playgroud)

在 Objective-C 中按预期工作

- (void)methodWithMyEnum:(MyEnum)myEnum { }
Run Code Online (Sandbox Code Playgroud)

和斯威夫特

func method(_ myEnum: MyEnum) { }
Run Code Online (Sandbox Code Playgroud)

  • 令人惊讶的是,在这之前我不得不阅读多少错误的答案。我知道它存在,而且我知道必须有一个新的 ObjC 编译器指令来实现这一点 - 同样的方式引入“非可选”以更平滑地与 swift 桥接。但我怎么也找不到苹果文档。伟大的。谢谢。 (3认同)

Ger*_*eri 9

这将由编译器验证,因此您不会意外混淆索引.

NSDictionary *stateStrings =
 @{
   @(MCSessionStateNotConnected) : @"MCSessionStateNotConnected",
   @(MCSessionStateConnecting) : @"MCSessionStateConnecting",
   @(MCSessionStateConnected) : @"MCSessionStateConnected",
  };
NSString *stateString = [stateStrings objectForKey:@(state)];
Run Code Online (Sandbox Code Playgroud)

var stateStrings: [MCSessionState: String] = [
    MCSessionState.NotConnected : "MCSessionState.NotConnected",
    MCSessionState.Connecting : "MCSessionState.Connecting",
    MCSessionState.Connected : "MCSessionState.Connected"
]
var stateString = stateStrings[MCSessionState.Connected]
Run Code Online (Sandbox Code Playgroud)


sup*_*org 8

2017年更新

最近的投票引起了我的注意,我想补充说enum现在很容易使用String:

enum HTTPMethod: String {
    case GET, POST, PUT
}

HTTPMethod.GET.rawValue == "GET" // it's true
Run Code Online (Sandbox Code Playgroud)

原始答案不幸的是我最终使用:


#define HLCSRestMethodGet       @"GET"
#define HLCSRestMethodPost      @"POST"
#define HLCSRestMethodPut       @"PUT"
#define HLCSRestMethodDelete    @"DELETE"
typedef NSString*               HLCSRestMethod;
Run Code Online (Sandbox Code Playgroud)

我知道这不是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
    }
Run Code Online (Sandbox Code Playgroud)

}

  • 问题是关于在 Objective-C 中引入此类枚举 NSString。不是斯威夫特。 (3认同)