and*_*n22 4 c xml cocoa enums objective-c
在XML中存储枚举并再次读取它的最简洁方法是什么?说我有:
enum ETObjectType {ETNormalObjectType, ETRareObjectType, ETEssentialObjectType};
Run Code Online (Sandbox Code Playgroud)
......我想利用一个变量,enum ETObjectType objectType = ETNormalObjectType;并将其转换为XML,看起来像这样:<objectType>ETNormalObjectType</objectType>.
目前我正在做的是这样的:
NSString* const ETObjectTypeAsString[] = {@"ETNormalObjectType",@"ETRareObjectType",@"ETEssentialObjectType"};
[anXMLElement addChild:[NSXMLElement elementWithName:@"objectType" stringValue:ETObjectTypeAsString[objectType]]];
Run Code Online (Sandbox Code Playgroud)
......但这并不完全理想; 每次更改枚举时,我都不满意更新两个列表.但这是可以接受的.更糟糕的是读回XML,我目前正在这样做:
if ([[[anXMLElement childNamed:@"objectType"] stringValue] isEqualToString:@"ETRareObjectType"])
{
[self initObjectType:ETRareObjectType];
}
else if ([[[anXMLElement childNamed:@"objectType"] stringValue] isEqualToString:@"ETEssentialObjectType"])
{
[self initObjectType:ETEssentialObjectType];
}
else
{
[self initObjectType:ETNormalObjectType];
}
Run Code Online (Sandbox Code Playgroud)
呸!这让我很反感.必须有一种更清晰的方式来阅读,至少,或者可能是一种统一的读写方式?
我正在使用Obj-C和Cocoa,但我不介意一些纯C函数.我甚至会使用预处理器的东西,如果这是唯一的方法.
Pet*_*wis 17
我没有找到比复制字符串中的枚举更好的方法.但是,我的做法略有不同,即:
typedef enum {
kManipulateWindowTargetFrontWindow,
kManipulateWindowTargetNamedWindow,
kManipulateWindowTargetWindowNameContaining,
kManipulateWindowTargetDEFAULT = kManipulateWindowTargetFrontWindow,
} ManipulateWindowTargetType;
#define kManipulateWindowTargetTypeNamesArray @"FrontWindow", @"NamedWindow", @"WindowNameContaining", nil
Run Code Online (Sandbox Code Playgroud)
然后在实施中:
static NSArray* kManipulateWindowTargetTypeArray = [[NSArray alloc] initWithObjects: kManipulateWindowTargetTypeNamesArray];
NSString* ManipulateWindowTargetTypeToString( ManipulateWindowTargetType mwtt )
{
return [kManipulateWindowTargetTypeArray objectAtIndex:mwtt];
}
ManipulateWindowTargetType ManipulateWindowTargetTypeFromString( NSString* s )
{
NSUInteger n = [kManipulateWindowTargetTypeArray indexOfObject:s];
check( n != NSNotFound );
if ( n == NSNotFound ) {
n = kManipulateWindowTargetDEFAULT;
}
return (ManipulateWindowTargetType) n;
}
Run Code Online (Sandbox Code Playgroud)
我使用#define的原因是为了避免在头文件中声明数组,但是将枚举的定义与字符串序列的定义分开是疯狂的,所以这是我发现的最好的折衷方案.
由于代码是样板文件,因此您实际上可以在NSArray上将它们作为类别.
@interface NSArray (XMLExtensions)
- (NSString*) stringWithEnum: (NSUInteger) e;
- (NSUInteger) enumFromString: (NSString*) s default: (NSUInteger) def;
- (NSUInteger) enumFromString: (NSString*) s;
@end
@implementation NSArray (XMLExtensions)
- (NSString*) stringWithEnum: (NSUInteger) e;
{
return [self objectAtIndex:e];
}
- (NSUInteger) enumFromString: (NSString*) s default: (NSUInteger) def;
{
NSUInteger n = [self indexOfObject:s];
check( n != NSNotFound );
if ( n == NSNotFound ) {
n = def;
}
return n;
}
- (NSUInteger) enumFromString: (NSString*) s;
{
return [self enumFromString:s default:0];
}
@end
Run Code Online (Sandbox Code Playgroud)
然后:
NSLog( @"s is %@", [kManipulateWindowTargetTypeArray stringWithEnum:kManipulateWindowTargetNamedWindow] );
ManipulateWindowTargetType mwtt = (ManipulateWindowTargetType)[kManipulateWindowTargetTypeArray enumFromString:@"WindowNameContaining" default:kManipulateWindowTargetDEFAULT];
NSLog( @"e is %d", mwtt );
Run Code Online (Sandbox Code Playgroud)
以下是我通常编写这些样式方法的方法:
#define countof(array) (sizeof(array)/sizeof(array[0]))
enum {
ETNormalObjectType,
ETRareObjectType,
ETEssentialObjectType
};
typedef NSInteger ETObjectType;
NSString *ETObjectTypesAsStrings[] = {[ETNormalObjectType] = @"ETNormalObjectType",
[ETRareObjectType] = @"ETRareObjectType",
[ETEssentialObjectType] = @"ETEssentialObjectType"};
NSString *ETStringFromObjectType(ETObjectType type) {
return ETObjectTypesAsStrings[type];
}
ETObjectType ETObjectTypeFromString(NSString *string) {
NSString *match = nil;
for(NSInteger idx = 0; !match && (idx < countof(ETObjectTypesAsStrings)); idx += 1) {
if ([string isEqualToString:ETObjectTypesAsStrings[idx]]) {
match = ETObjectTypesAsStrings[idx];
}
}
return match;
}
Run Code Online (Sandbox Code Playgroud)
您最终必须将枚举值放在两个位置,即原始枚举,以及将整数值映射到其字符串名称的数组.实际执行映射的两个函数虽然没有映射的副本.
小智 5
我回应Jon的解决方案,但你可以使用可怕的X-macro来避免重复自己.我不知道如何评论Jon的代码格式化答案,所以这里作为一个新的答案.
#define ETObjectTypeEntries \
ENTRY(ETNormalObjectType) \
ENTRY(ETRareObjectType) \
ENTRY(ETEssentialObjectType)
typedef enum ETObjectType {
#define ENTRY(objectType) objectType,
ETObjectTypeEntries
#undef ENTRY
} ETObjectType;
NSString *ETObjectTypesAsStrings[] = {
#define ENTRY(objectType) [objectType] = @"" # objectType,
ETObjectTypeEntries
#undef ENTRY
};
#define countof(array) (sizeof(array)/sizeof(array[0]))
NSString *ETStringFromObjectType(ETObjectType type) {
return ETObjectTypesAsStrings[type];
}
NSString *ETObjectTypeFromString(NSString *string) {
NSString *match = nil;
for(NSInteger idx = 0; !match && (idx < countof(ETObjectTypesAsStrings)); idx += 1) {
if ([string isEqualToString:ETObjectTypesAsStrings[idx]]) {
match = ETObjectTypesAsStrings[idx];
}
}
return match;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6882 次 |
| 最近记录: |