您的位置:首页 > 运维架构

NS_ENUM vs. NS_OPTIONS

2016-03-04 18:31 411 查看
NS_ENUM用于定义普通枚举值,NS_OPTIONS用于定义位移相关操作的枚举值:

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来定义。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: