NS_ENUM vs. NS_OPTIONS
2016-03-04 18:31
411 查看
NS_ENUM用于定义普通枚举值,NS_OPTIONS用于定义位移相关操作的枚举值:
根据是否要将代码按C++模式编译,NS_OPTIONS宏的定义方式有所不同。如果不按C++编译,那么其展开方式就和NS_ENUM相同。若按C++编译,则展开后的代码略有不同。原因在于,用按位或运算来操作两个枚举值时,C++编译模式的处理办法与非C++模式不一样。作为选项的枚举值经常需要用按位或运算来组合,在用或运算操作两个枚举值时,C++认为运算结果的数据类型应该是枚举的底层数据类型,也就是NSUInteger,而且C++不允许将这个底层类型“隐式转换”(implicit cast)为枚举类型本身。
我们用EOCPermittedDirection来演示一下,假设按NS_ENUM方式将其展开:
然后考虑下列代码:
若编译器按C++模式编译(也可能是按Objective-C++模式编译),则会给出下列错误信息:
如果想编译这行代码,就要将按位或操作的结果显式转换(explicit cast)为EOCPermittedDirection。所以,在C++模式下应该用另一种方式定义NS_OPTIONS宏,以便省去类型转换操作。鉴于此,凡是需要以按位或操作来组合的枚举都应使用NS_OPTIONS定义。若是枚举不需要互相组合,则应使用NS_ENUM来定义。
typedef NS_ENUM(NSUInteger, EOCConnectionState) { EOCConnectionStateDisconnected, EOCConnectionStateConnecting, EOCConnectionStateConnected, }; typedef NS_OPTIONS(NSUInteger, EOCPermittedDirection) { EOCPermittedDirectionUp = 1 << 0, EOCPermittedDirectionDown = 1 << 1, EOCPermittedDirectionLeft = 1 << 2, EOCPermittedDirectionRight = 1 << 3, };
根据是否要将代码按C++模式编译,NS_OPTIONS宏的定义方式有所不同。如果不按C++编译,那么其展开方式就和NS_ENUM相同。若按C++编译,则展开后的代码略有不同。原因在于,用按位或运算来操作两个枚举值时,C++编译模式的处理办法与非C++模式不一样。作为选项的枚举值经常需要用按位或运算来组合,在用或运算操作两个枚举值时,C++认为运算结果的数据类型应该是枚举的底层数据类型,也就是NSUInteger,而且C++不允许将这个底层类型“隐式转换”(implicit cast)为枚举类型本身。
我们用EOCPermittedDirection来演示一下,假设按NS_ENUM方式将其展开:
typedef enum EOCPermittedDirection : int EOCPermittedDirection; enum EOCPermittedDirection : int { EOCPermittedDirectionUp = 1 << 0, EOCPermittedDirectionDown = 1 << 1, EOCPermittedDirectionLeft = 1 << 2, EOCPermittedDirectionRight = 1 << 3, };
然后考虑下列代码:
OCPermittedDirection permittedDirections = EOCPermittedDirectionLeft | EOCPermittedDirectionUp;
若编译器按C++模式编译(也可能是按Objective-C++模式编译),则会给出下列错误信息:
error: cannot initialize a variable of type 'EOCPermittedDirection' with an rvalue of type 'int'
如果想编译这行代码,就要将按位或操作的结果显式转换(explicit cast)为EOCPermittedDirection。所以,在C++模式下应该用另一种方式定义NS_OPTIONS宏,以便省去类型转换操作。鉴于此,凡是需要以按位或操作来组合的枚举都应使用NS_OPTIONS定义。若是枚举不需要互相组合,则应使用NS_ENUM来定义。
相关文章推荐
- Linux多线程及同步
- shell 编程笔记
- linux scp远程拷贝文件及文件夹
- Linux系统中MySQL数据库操作命令(未整理)
- An instance of “(null)” is already running. Choose “Stop” to terminate and launch a new instance.
- Linux 后台进程与守护进程
- Linux统计某文件夹下文件、文件夹的个数
- Please verify that your device’s clock is properly set, and that your signing certificate is not exp
- Properties
- Linux常用目录的作用
- linux运维实战练习-2016年3月4日-3月19日课程作业(练习)安排
- Linux内核文件系统学习:虚拟文件系统(多图)
- 安装Linux后需要了解的
- linux逻辑卷管理
- linux下命令行安装hadoop2.7.2过程
- 命令模式下的异步消息处理(Handler,Message,Looper,Thread)
- apache mod_concatx模块 合并多个js/css 提高网页加载速度
- 关于NSString的copy和mutableCopy
- XManage-xshell批量指令
- 利用__index和__newindex实现默认值表、监控表、只读表(转)