Jonathan's Studio

OC-枚举的学问

字数统计: 844阅读时长: 3 min
2020/03/05

定义一个枚举

1
2
3
4
5
6
7
8
9

typedef NS_ENUM(NSInteger, CYLSex) {

CYLSexMan,

CYLSexWoman

};

你有可能会是这样写的

1
2
3
4
5
6
7
8
9

typedef enum{

UserSex_Man,

UserSex_Woman

}UserSex;

enum 建议使用 NS_ENUM 和 NS_OPTIONS 宏来定义枚举类型

为什么呢?

因为他们除了推断出不同类型的枚举,再就是当编译 Objective-C++模式,它们产生的代码是不同的, 就是因为不同所以混编的时候使用 enum 会报错!

命名应该科学严谨具有依据,在英文不应是含糊的。其次命名上具有继承性 这里 sex 跟性有关 gender 对于众多软件设计中更为妥当

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

//NS_ENUM,定义状态等普通枚举

typedef NS_ENUM(NSUInteger, TTGState) {

TTGStateOK = 0,

TTGStateError,

TTGStateUnknow

};



//NS_OPTIONS,定义选项

typedef NS_OPTIONS(NSUInteger, TTGDirection) {

TTGDirectionNone = 0,

TTGDirectionTop = 1 << 0,

TTGDirectionLeft = 1 << 1,

TTGDirectionRight = 1 << 2,

TTGDirectionBottom = 1 << 3

};



来自官方的例子

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

//UIControl的枚举

typedef NS_OPTIONS(NSUInteger, UIControlEvents) {

UIControlEventTouchDown = 1 << 0, // on all touch downs

UIControlEventTouchDownRepeat = 1 << 1, // on multiple touchdowns (tap count > 1)

UIControlEventTouchDragInside = 1 << 2,

UIControlEventTouchDragOutside = 1 << 3,

UIControlEventTouchDragEnter = 1 << 4,

UIControlEventTouchDragExit = 1 << 5,

UIControlEventTouchUpInside = 1 << 6,

UIControlEventTouchUpOutside = 1 << 7,

UIControlEventTouchCancel = 1 << 8,



UIControlEventValueChanged = 1 << 12, // sliders, etc.

UIControlEventPrimaryActionTriggered NS_ENUM_AVAILABLE_IOS(9_0) = 1 << 13, // semantic action: for buttons, etc.



UIControlEventEditingDidBegin = 1 << 16, // UITextField

UIControlEventEditingChanged = 1 << 17,

UIControlEventEditingDidEnd = 1 << 18,

UIControlEventEditingDidEndOnExit = 1 << 19, // 'return key' ending editing



UIControlEventAllTouchEvents = 0x00000FFF, // for touch events

UIControlEventAllEditingEvents = 0x000F0000, // for UITextField

UIControlEventApplicationReserved = 0x0F000000, // range available for application use

UIControlEventSystemReserved = 0xF0000000, // range reserved for internal framework use

UIControlEventAllEvents = 0xFFFFFFFF

};





//随便添加一个UITextField

UITextField *field = [UITextField new];

//Begin,Changed,DidEnd都能触发UITextField的事件

[field addTarget:self action:@selector(textFieldDidChanged) forControlEvents: UIControlEventEditingDidBegin |

UIControlEventValueChanged |

UIControlEventEditingDidEnd

];



枚举值中有<<(位运算符:左移) 那我们就可以通过|(位运算符:或)进行组合使用如下代码为例

位运算符 <<(左移):a << b 就表示把 a 转为二进制后左移 b 位(在后面添 b 个 0) 如果 1 << 2 其值为 4 2 的 2 次方

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63



这里举个例子



nameA = 1 << 0 :值为1(2的0次方)

nameB = 1 << 1 :值为2(2的1次方)

nameC = 1 << 2 :值为4(2的2次方)

nameD = 1 << 3 :值为8(2的3次方)



NSInteger value = nameA | nameB | nameC | nameD;

转成二进制:

nameA: 0 0 0 1

|

nameB: 0 0 1 0

|

nameC: 0 1 0 0

|

nameD: 1 0 0 0

----------------

value: 1 1 1 1

上面是使用 | 得出value的值为1111 十进制为15



NSInteger result = value & nameA

转成二进制:

value: 1 1 1 1

&

nameA: 0 0 0 1

----------------

result: 0 0 0 1



上面是使用 | 得出value的值为0001



可以看出 apple 在判断 NS_OPTIONS 的多个选择的时候,是通过&运算判断的

补充

NS_ENUM:是用来声明一般的 NSInteger(代码使用 NSInteger)类型的枚举

Use the NS_ENUM macro to define enumerations, a set of values that are mutually exclusive.

NS_OPTIONS:是用来声明位掩码(bitmasked)

Use the NS_OPTIONS macro to define options, a set of bitmasked values that may be combined together.

首先,NS_ENUM 使用 C 语言的一个新特性,您可以在该特性中指定 enum 的底层类型。在本例中,enum 的底层类型是 NSInteger(在普通的 C 语言中,它是编译器决定的任何类型,char、short,甚至是编译器喜欢的 24 位整数)。

其次,编译器专门识别 NS_ENUM 宏,因此它知道您有一个 enum,它的值不应该像标志那样组合在一起,调试器知道发生了什么,并且 enum 可以自动转换为 Swift。

CATALOG
  1. 1. 定义一个枚举
  2. 2. 你有可能会是这样写的
  3. 3. enum 建议使用 NS_ENUM 和 NS_OPTIONS 宏来定义枚举类型
  4. 4. 为什么呢?
  5. 5. 来自官方的例子
  • 补充