Im копание путей для перечисления объекта objc, такого как NSString, я помню там новую функцию в версии Xcode4 +, которая предлагает новый способ перечисления, но не ясно. Кто-нибудь знает это?
Лучший способ перечислить NSString
Ответ 1
Хорошо, я ответил себе. Думаю, я ошибаюсь.
Это новая функция, о которой я упоминал выше:
typedef enum Language : NSUInteger{
ObjectiveC,
Java,
Ruby,
Python,
Erlang
}Language;
Это просто новый синтаксис перечисления в 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;
}
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
Ответ 2
Альтернативный способ использования 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;
Простой в использовании, читаемый. Было бы неплохо, если бы кто-то обновил/отредактировал ответ с преимуществами/недостатками подхода выше.
Ответ 3
Это будет подтверждено компилятором, поэтому вы случайно не будете смешивать индексы.
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]
Ответ 4
Обновление в 2017 году
Недавние голосовые комментарии привлекли мое внимание, и я хотел бы добавить, что enum
действительно легко работать с String
сейчас:
enum HTTPMethod: String {
case GET, POST, PUT
}
HTTPMethod.GET.rawValue == "GET" // it true
Оригинальный ответ. К сожалению, я закончил использование:
#define HLCSRestMethodGet @"GET"
#define HLCSRestMethodPost @"POST"
#define HLCSRestMethodPut @"PUT"
#define HLCSRestMethodDelete @"DELETE"
typedef NSString* HLCSRestMethod;
Я знаю, что это не то, что задал ОП, но написание реального кода для реализации перечисления, похоже, для меня является излишним. Я бы рассмотрел перечисление как функцию языка (от C), и если мне нужно написать код, я бы предложил некоторые более качественные классы, которые делают больше, чем перечисление.
Update
Быстрая версия кажется более красивой, хотя производительность никогда не будет такой хорошей.
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
}
}
Ответ 5
Я думаю, что вы ищете встроенную функцию массива. например,
@[@"stringone",@"stringtwo",@"stringthree"];
Если нет, я не уверен, что вы можете перечислять объекты.
вы могли бы иметь статический массив строк и иметь ссылочный объект перечисления в индексе.
Ответ 6
Посмотрите мой ответ в enum Значения для NSString (iOS) - Я считаю, что это может быть более элегантное решение этой проблемы.
Ответ 7
Рекомендуемый способ из яблочных документов:
Вы используете NS_TYPED_ENUM для группировки констант с указанным вами типом необработанного значения. Используйте NS_TYPED_ENUM для наборов констант, которые не могут логически иметь значения, добавленные в расширение Swift, и используйте NS_TYPED_EXTENSIBLE_ENUM для наборов констант, которые могут быть расширены в расширении. Apple, документы
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 { }
и Свифт
func method(_ myEnum: MyEnum) { }