ios-枚举类型

在ios中的枚举类型一般来说有两种一种是NS_ENUM,另外一种是NS_OPTIONS。两者都可以去指定枚举的值的数据类型

如果是NS_OPTIONS的话就可以用按位或来一起的去设置数值,就比如说下面这个我们就可以用 | 符号来连接。这里的UL是unsigned long的意思

typedef NS_OPTIONS(NSUInteger, NSJSONReadingOptions) {
    NSJSONReadingMutableContainers = (1UL << 0),
    NSJSONReadingMutableLeaves = (1UL << 1),
    NSJSONReadingAllowFragments = (1UL << 2)
}
我们一般来说如果要用到这样的枚举传个0就表示什么都不做。


下面是NS_ENUM的

typedef NS_ENUM(NSInteger, UIViewAnimationCurve) {
    UIViewAnimationCurveEaseInOut,         // slow at beginning and end
    UIViewAnimationCurveEaseIn,            // slow at beginning
    UIViewAnimationCurveEaseOut,           // slow at end
    UIViewAnimationCurveLinear,
};

这里简单的介绍下上面两者的区别

一个是可以进行 | 运算,这样的话设置枚举项的时候就可以定义为两个枚举项都支持了,也就是说。位移枚举即是在你需要的地方可以同时存在多个枚举值。其中关于| 运算,对应二进制位做运算,只要相对应的二进制位有一个为1,则就为1

下面是示例

 UISwipeGestureRecognizer *gesture = [[UISwipeGestureRecognizer alloc]init];    
//添加了下滑、右滑、左滑手势
gesture.direction = UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight;

但是如果是NS_ENUM的话是不可以这样的。只能单独取值。


那么为什么NS_ENUM不行呢?

因为使用NS_OPTIONS来定义枚举值的时候.每个枚举项所对应的二进制表示中,只有1个二进制的值是1,用按位或就可以可组合多个选项.例如:UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionLeft,用按位与操作符既可以判断出是否已经设置了某个选项,但是NS_ENUM就不行了,因为它的枚举项的二进制并不是只有一个1的。


这里再介绍下关于NS_OPTIONS和NS_ENUM的宏定义,如下所示

首先判断的是编译器是否支持新式枚举。这个的意思就是想判断编译器是否支持新的枚举特性。如果不支持,那么就用老式的语法来定义枚举,老式的枚举NS_OPTIONS和NS_ENUM的宏是一样的。这个新式枚举是在C++11标准中被提出的。

在第三行判断的是是否要将代码按C++模式编译,因为按照C++模式编译和不按照C++模式进行编译,NS_OPTIONS的宏展开是不一样的。为什么?

因为根据是否要将代码按C++模式编译,NS_OPTIONS宏的定义方式也有所不同。如果不按C++编译,那么其展开方式就和NS_ENUM相同。

#if (__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && __has_feature(objc_fixed_enum))
#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
#if (__cplusplus)
#define NS_OPTIONS(_type, _name) _type _name; enum : _type
#else
#define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type
#endif
#else
#define NS_ENUM(_type, _name) _type _name; enum
#define NS_OPTIONS(_type, _name) _type _name; enum
#endif

这里可以测试下按照C++编译模式下,这样做是会报错的,先写一个枚举,然后按照上面定义的规则展开

typedef enum Direction : int Direction;

enum Direction : int {
     DirectionUp    = 1 << 0,
     DirectionDown  = 1 << 1,
     DirectionLeft  = 1 << 2,
     DirectionRight = 1 << 3,
};

可以看到下面是报错了的,为什么会报错?因为C++编译模式的处理办法与非C++模式不一样。作为选项的枚举值经常需要用按位或运算来组合。在用或运算操作两个枚举值时,C++认为运算结果的数据类型应该是枚举的底层数据类型,也就是int。而且C++不允许将这个运算完成的底层类型再去做隐式转换为枚举类型本身。


所以我们其实只需要在=的后面加一个Direction进行显示转换一下就可以了,所以在非C++编译模式下我们NS_OPTIONS宏定义其实就是把NS_OPTIONS(_type,_name)中的_name变成了_type的别名所以就没关系了。


C语言定义枚举的方式可以如下所示定义

typedef enum  {
   A,
   B,
   C,
}ZXTime;
也还可以这么定义


enum ZXkk{
   AB,
   BC,
   CD,
};

这两者的区别就在于一个定义枚举类型的时候第一个直接这么定义就可以了 ZXTime mkl=A;  第二个要这么定义 enum  ZXkk mkl = A;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值