Objective-C枚举的使用,常见的方式总结,以便自己使用时方便查阅。
1. 枚举介绍
enum only
| 1
2
3
4
5
 | enum
{
    TMEnumTestOne,
    TMEnumTestTwo,
};
 | 
- 这种枚举不推荐使用,因为不能用一种类型的方式表示枚举。
enum 类型
| 1
2
3
4
5
6
 | typedef enum
{
    TMEnumTestOne,
    TMEnumTestTwo,
} TMEnumTest;
 | 
| 1
2
3
4
5
6
 | enum TMEnumTest
{
    TMEnumTestOne,
    TMEnumTestTwo,
};
typedef enum TMEnumTest TMEnumTest;
 | 
- 这两种写法,将枚举描述为一个类型TMEnumTest。 
 但是这种写法也有局限性,在作为函数参数时,如果传入NSInteger类型的数据,则需要强制转换,否则会有类型不匹配的警告,所以这种方式也不推荐。如下图, 
老式enum写法
| 1
2
3
4
5
6
 | enum
{
    TMEnumTestOne,
    TMEnumTestTwo,
};
typedef NSUInteger TMEnumTest;
 | 
- 这种写法可以指定TMEnumTest的类型,并且作为函数参数时,传入的值不需要进行强制类型转换。 
 但是这种写法不会检查枚举的正确性,是好是坏需要自己判断,如下图。本人推荐这种写法。 
新式enum写法
| 1
2
3
4
5
 | typedef NS_ENUM(NSUInteger, TMEnumTest)
{
    TMEnumTestOne,
    TMEnumTestTwo,
};
 | 
| 1
2
3
4
5
 | typedef NS_OPTIONS(NSUInteger, TMEnumTest)
{
    TMEnumTestOne  = 0,
    TMEnumTestTwo  = 1 << 0,
};
 | 
- NS_ENUM和NS_OPTIONS本质是一样的,仅仅从字面上来区分用途。NS_ENUM是通用情况,NS_OPTIONS一般用来定义位枚举。
参考链接
- 这种写法同样作为函数参数时,传入的值不需要进行强制类型转换。但是也同样不会检查枚举的正确性,和 老式enum写法 一样,如下图。
 
- 但是不同的是,新式enum写法 在使用switch时,会进行值的检测,如果枚举中无此值,则会弹出警告,如下图。这种方式见仁见智了。本人推荐这种写法。
 
2. 枚举最大值
对于一般的枚举,要获取枚举的最大值是很难的,因为随着枚举的扩充,最大值在不断变化,这时推荐使用一个固定的枚举表示最大值,例如:
| 1
2
3
4
5
6
7
 | typedef NS_ENUM(NSUInteger, TMEnumTest)
{
    TMEnumTestOne,
    TMEnumTestTwo,
    TMEnumTestMax,  // 表示最大值
};
 | 
这样就可以使用TMEnumTestMax表示枚举TMEnumTest的最大值了。
3. 位枚举
位枚举是一种特殊的枚举,在apple的类中使用的很多,例如NSStringCompareOptions等。
| 1
2
3
4
5
6
7
 | typedef NS_OPTIONS(NSUInteger, TMEnumTest)
{
    TMEnumTestOne     = 0,          // 0
    TMEnumTestTwo     = 1 << 0,     // 1
    TMEnumTestThree   = 1 << 1,     // 2
    TMEnumTestFour    = 1 << 2,     // 4
};
 | 
- 位枚举的特点是可以使用位运算来处理枚举值,实际使用中可以用一个变量存储多个枚举值,表示互不影响的多个设置。
| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 | - (void) test
{
    TMEnumTest test = TMEnumTestTwo|TMEnumTestThree;  // 3
    /* 添加TMEnumTestFour到test中(如test已经包含TMEnumTestFour,则test值不变)
    
       当然这里也可以使用test += TMEnumTestFour,
       但是注意 + 不能在test中已经包含TMEnumTestFour的情况下使用。
    */
    test |= TMEnumTestFour;  // 7
    /* 将TMEnumTestThree从test中去除(如test不包含TMEnumTestThree,则test值不变)
    
       当然这里也可以使用test -= TMEnumTestThree,
       但是注意 - 不能在test中不包含TMEnumTestThree的情况下使用。
    */
    test &= ~TMEnumTestThree; // 5
    // 判断 TMEnumTestFour枚举 是否被包含
    if ((test & TMEnumTestFour) == TMEnumTestFour)
    {
        NSLog(@"YES");
    }
    /* 判断 TMEnumTestFour枚举 是否被包含
     
     因为 (test & TMEnumTestFour) 的结果不是 0,就是TMEnumTestFour本身,
     而 TMEnumTestFour > 0 ,所以可以使用简易的判断
     */
    if (test & TMEnumTestFour)
    {
        NSLog(@"YES");
    }
}
 |