Best way to enum NSString

前端 未结 7 694
广开言路
广开言路 2021-02-02 13:23

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

相关标签:
7条回答
  • 2021-02-02 13:24

    Update in 2017

    Recent down votes drew my attention, and I'd like to add that enum is really easy to work with String now:

    enum HTTPMethod: String {
        case GET, POST, PUT
    }
    
    HTTPMethod.GET.rawValue == "GET" // it's true
    

    Original Answer

    Unfortunately 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.

    Update

    Swift version seems to be prettier, although the performance can never be as good.

    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
        }
    

    }

    0 讨论(0)
  • 2021-02-02 13:28

    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

    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

    MyEnum const MyEnumFirstValue = @"MyEnumFirstValue"
    MyEnum const MyEnumSecondValue = @"MyEnumSecondValue";
    MyEnum const MyEnumThirdValue = @"MyEnumThirdValue";
    

    Works as expected in both Objective-C

    - (void)methodWithMyEnum:(MyEnum)myEnum { }
    

    and Swift

    func method(_ myEnum: MyEnum) { }
    
    0 讨论(0)
  • 2021-02-02 13:28

    See my answer at enum Values to NSString (iOS) - I believe that might be a more elegant solution to this issue.

    0 讨论(0)
  • 2021-02-02 13:32

    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".

    So here is the way I found that works:

    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.

    @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
    
    0 讨论(0)
  • 2021-02-02 13:44

    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.

    0 讨论(0)
  • 2021-02-02 13:46

    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 this approach.

    0 讨论(0)
提交回复
热议问题