ios - type - La mejor forma de enumerar NSString
switch self swift (6)
Estoy buscando formas de enumerar objc objeto como NSString, recuerdo que hay una nueva característica en una versión de Xcode4 + que ofrece una nueva forma de enumerar, pero no claramente. Alguien sabe eso?
Creo que estás buscando la función de matriz en línea. p.ej
@[@"stringone",@"stringtwo",@"stringthree"];
si no, no estoy seguro de poder enumerar objetos.
Sin embargo, podría tener una matriz estática de cadenas y tener el objeto de referencia enum en el índice.
OK, me contesté a mí mismo. Supongo que me equivoco.
Esta es la nueva característica que mencioné arriba:
typedef enum Language : NSUInteger{
ObjectiveC,
Java,
Ruby,
Python,
Erlang
}Language;
Es una nueva sintaxis para enum en Xcode 4.4, pero soy tan tonto como para pensar que podemos intercambiar "NSUInteger" por "NSString".
Así que aquí está la forma en que descubrí que funciona:
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. El autor original del segundo código de ejemplo creó una categoría para el manejo de enum. Justo lo que se necesita para agregar a su propia definición de clase 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
Manera alternativa de usar 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"
};
Entonces puedes usar esto:
NSString *status = AMPlayerState.ready;
Fácil de usar, legible PD: perdón por la respuesta incompleta sobre las ventajas / desventajas de rendimiento
Esto será validado por el compilador, por lo que no confundirá los índices accidentalmente.
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]
Ver mi respuesta en enum Values to NSString (iOS) : creo que podría ser una solución más elegante para este problema.
Actualización en 2017
Recientes votos a la baja me llamaron la atención, y me gustaría añadir que enum
es realmente fácil trabajar con String
ahora:
enum HTTPMethod: String {
case GET, POST, PUT
}
HTTPMethod.GET.rawValue == "GET" // it''s true
Respuesta original Desafortunadamente terminé usando:
#define HLCSRestMethodGet @"GET"
#define HLCSRestMethodPost @"POST"
#define HLCSRestMethodPut @"PUT"
#define HLCSRestMethodDelete @"DELETE"
typedef NSString* HLCSRestMethod;
Sé que esto no es lo que OP pidió, pero escribir el código real para implementar enum parece ser un exceso para mí. Consideraría la enumeración como una función de lenguaje (de C) y si tuviera que escribir código, obtendría algunas clases mejores que hacen más que enum.
Actualizar
La versión Swift parece ser más bonita, aunque el rendimiento nunca puede ser tan bueno.
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
}
}