获得项目数为NS_ENUM的优雅的方式 [英] Elegant way of getting number of items for NS_ENUM

查看:116
本文介绍了获得项目数为NS_ENUM的优雅的方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有得到一个NS_ENUM项目总数的优雅的方式?和最大值?


一些例子:

 的typedef NS_ENUM(NSInteger的,MyEnum)
{
    MyEnumA = 0,
    MyEnumB = 1,
    MyEnumC = 2
};
// NumberOfItems(MyEnum) - > 3,MaximumValue(MyEnum) - GT; 2。
的typedef NS_ENUM(NSInteger的,MyEnum)
{
    MyEnumA,
    MyEnumB,
    MyEnumC
};
// NumberOfItems(MyEnum) - > 3,MaximumValue(MyEnum) - GT; 2。
的typedef NS_ENUM(NSInteger的,MyEnum)
{
    MyEnumA = 4,
    MyEnumB,
    MyEnumC
};
// NumberOfItems(MyEnum) - > 3,MaximumValue(MyEnum) - GT; 6。
的typedef NS_ENUM(NSInteger的,MyEnum)
{
    MyEnumA = 0,
    MyEnumB = 2,
    MyEnumC = 4
};
// NumberOfItems(MyEnum) - > 3,MaximumValue(MyEnum) - GT; 4。


解决方案

不幸的是,C枚举(其中 NS_ENUM 宏是一个发电机)都相当简单,没有反思

如果您的枚举值是连续的,它的简单让使用极限值的项目数:

 的typedef NS_ENUM(NSInteger的,MyEnum){
    MyEnumA = 0,
    MyEnumB,
    MyEnumC,
    MyEnumMax
};NSUInteger numItems的= MyNumMax;

然而,这并不是因为当你写一个开关的理想解决方案,你会得到一个警告,如果你不添加情况MyEnumMax:(或默认值:)。

您最好的选择就是为每个枚举创建信息功能:

 的typedef NS_ENUM(NSInteger的,MyEnum){
    MyEnumA = 0,
    MyEnumB = 2,
    MyEnumC = 4,
};NSUInteger MyEnumSize(){
   返回3;
}

您也可以使用如的X宏一些高级宏观技术来生成这个函数动态。

大警告:X-宏并不简单,不容易阅读,但他们是强大的。举例如下:

MyEnum.h

 的#define MY_ENUM_DEFINITIONS \\
    NS_ENUM_X_VALUE(MyEnumA,= 0)\\
    NS_ENUM_X_VALUE(MyEnumB,)\\
    NS_ENUM_X_VALUE(MyEnumC,= 4)#定义NS_ENUM_X_VALUE(__ NAME__,__INT_VALUE__)__name__ __INT_VALUE__,的typedef NS_ENUM(NSInteger的,MyEnum){
    MY_ENUM_DEFINITIONS
};和#undef NS_ENUM_X_VALUE* NSString的NSStringFromMyEnum(MyEnum值);
NSArray的* MyEnumValues​​();
NSUInteger MyEnumSize();
NSUInteger MyEnumMin();
NSUInteger MyEnumMax();

MyEnum.m

 的#define NS_ENUM_X_VALUE(__ NAME__,__INT_VALUE__)__name__] = @#__ NAME__,静态的NSString * MyEnumStringTable [] = {
    MY_ENUM_DEFINITIONS
};和#undef NS_ENUM_X_VALUE* NSString的NSStringFromMyEnum(MyEnum值){
    返回MyEnumStringTable [值];
}#定义NS_ENUM_X_VALUE(__ NAME__,__INT_VALUE__)@(__ NAME__)静态NSOrderedSet * MyEnumValueSet(){
    静态NSOrderedSet * valueSet =零;
    静态dispatch_once_t onceToken;    dispatch_once(安培; onceToken,^ {
        valueSet = [[NSOrderedSet页头] initWithObjects:
        MY_ENUM_DEFINITIONS
        零];
    });    返回valueSet;
}和#undef NS_ENUM_X_VALUE
NSArray的* MyEnumValues​​(){
    返回[MyEnumValueSet()数组];
}NSUInteger MyEnumSize(){
    返回MyEnumValueSet()计数。
}NSUInteger MyEnumMin(){
    返回[MyEnumValueSet()firstObject unsignedIntegerValue。]
}NSUInteger MyEnumMax(){
    返回[MyEnumValueSet()lastObject unsignedIntegerValue。]
}

用法

 的NSLog(@MyEnum大小:%@,@(MyEnumSize()));
的NSLog(@MyEnum分钟:%@,@(MyEnumMin()));
的NSLog(@MyEnum最大值:%@,@(MyEnumMax()));的NSLog(@MyEnumC值字符串:%@,NSStringFromMyEnum(MyEnumC));对于(NSNumber的*在MyEnumValues​​值()){
    的NSLog(@价值上市:%@ = GT;%@,NSStringFromMyEnum([值unsignedIntegerValue]),价值);
}

现在可以修改/添加/删除值在标题中,你所有的功能将被自动更新。

Is there an elegant way of getting the total number of items in a NS_ENUM? And the maximum value?


Some examples:

typedef NS_ENUM(NSInteger, MyEnum)
{
    MyEnumA = 0,
    MyEnumB = 1,
    MyEnumC = 2
};
// NumberOfItems(MyEnum) -> 3, MaximumValue(MyEnum) -> 2.


typedef NS_ENUM(NSInteger, MyEnum)
{
    MyEnumA,
    MyEnumB,
    MyEnumC
};
// NumberOfItems(MyEnum) -> 3, MaximumValue(MyEnum) -> 2.


typedef NS_ENUM(NSInteger, MyEnum)
{
    MyEnumA = 4,
    MyEnumB,
    MyEnumC
};
// NumberOfItems(MyEnum) -> 3, MaximumValue(MyEnum) -> 6.


typedef NS_ENUM(NSInteger, MyEnum)
{
    MyEnumA = 0,
    MyEnumB = 2,
    MyEnumC = 4
};
// NumberOfItems(MyEnum) -> 3, MaximumValue(MyEnum) -> 4.

解决方案

Unfortunately, C enums (which NS_ENUM macro is a generator for) are rather simple, with no reflection.

If your enum values are consecutive, it's simple to get the number of items using limit values:

typedef NS_ENUM(NSInteger, MyEnum) {
    MyEnumA = 0,
    MyEnumB,
    MyEnumC,
    MyEnumMax 
};

NSUInteger numItems = MyNumMax;

However, this is not an ideal solution because when you write a switch, you will get a warning if you don't add a case MyEnumMax: (or default:).

Your best option then is to create info functions for every enum:

typedef NS_ENUM(NSInteger, MyEnum) {
    MyEnumA = 0,
    MyEnumB = 2,
    MyEnumC = 4,
};

NSUInteger MyEnumSize() {
   return 3;
}

You could also use some advanced macro techniques like X-macros to generate this function dynamically.

Big warning: X-macros are not simple, not easily readable but they are powerful. Example follows:

MyEnum.h

#define MY_ENUM_DEFINITIONS \
    NS_ENUM_X_VALUE(MyEnumA, = 0) \
    NS_ENUM_X_VALUE(MyEnumB,) \
    NS_ENUM_X_VALUE(MyEnumC, = 4)

#define NS_ENUM_X_VALUE(__NAME__, __INT_VALUE__) __NAME__ __INT_VALUE__,

typedef NS_ENUM(NSInteger, MyEnum) {
    MY_ENUM_DEFINITIONS
};

#undef NS_ENUM_X_VALUE

NSString * NSStringFromMyEnum(MyEnum value);
NSArray * MyEnumValues();
NSUInteger MyEnumSize();
NSUInteger MyEnumMin();
NSUInteger MyEnumMax();

MyEnum.m

#define NS_ENUM_X_VALUE(__NAME__, __INT_VALUE__) [__NAME__] = @#__NAME__,

static NSString* MyEnumStringTable[] = {
    MY_ENUM_DEFINITIONS
};

#undef NS_ENUM_X_VALUE

NSString * NSStringFromMyEnum(MyEnum value) {
    return MyEnumStringTable[value];
}

#define NS_ENUM_X_VALUE(__NAME__, __INT_VALUE__) @(__NAME__),

static NSOrderedSet * MyEnumValueSet() {
    static NSOrderedSet *valueSet = nil;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
        valueSet = [[NSOrderedSet alloc] initWithObjects:
        MY_ENUM_DEFINITIONS
        nil];
    });

    return valueSet;
}

#undef NS_ENUM_X_VALUE


NSArray *MyEnumValues() {
    return [MyEnumValueSet() array];
}

NSUInteger MyEnumSize() {
    return MyEnumValueSet().count;
}

NSUInteger MyEnumMin() {
    return [MyEnumValueSet().firstObject unsignedIntegerValue];
}

NSUInteger MyEnumMax() {
    return [MyEnumValueSet().lastObject unsignedIntegerValue];
}

Usage

NSLog(@"MyEnum size: %@", @(MyEnumSize()));
NSLog(@"MyEnum min: %@", @(MyEnumMin()));
NSLog(@"MyEnum max: %@", @(MyEnumMax()));

NSLog(@"MyEnumC value to string: %@", NSStringFromMyEnum(MyEnumC));

for (NSNumber *value in MyEnumValues()) {
    NSLog(@"Value listing: %@ => %@", NSStringFromMyEnum([value unsignedIntegerValue]), value);
}

Now you can modify/add/remove values in the header and all your functions will be updated automatically.

这篇关于获得项目数为NS_ENUM的优雅的方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆