NS_ENUM用于定义普通枚举值,NS_OPTIONS用于定义位移相关操作的枚举值:

typedef NS_ENUM(NSUInteger, EOCConnectionState) {
EOCConnectionStateDisconnected,
EOCConnectionStateConnecting,
EOCConnectionStateConnected,
}; typedef NS_OPTIONS(NSUInteger, EOCPermittedDirection) {
EOCPermittedDirectionUp = << ,
EOCPermittedDirectionDown = << ,
EOCPermittedDirectionLeft = << ,
EOCPermittedDirectionRight = << ,
};

根据是否要将代码按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 = << ,
EOCPermittedDirectionDown = << ,
EOCPermittedDirectionLeft = << ,
EOCPermittedDirectionRight = << ,
};

然后考虑下列代码:

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来定义。

NS_ENUM vs. NS_OPTIONS的更多相关文章

  1. NS_ENUM和NS_OPTIONS区别

    首先,NS_ENUM和NS_OPTIONS都是宏. Foundation框架中定义了一些辅助的宏,用这些宏来定义枚举类型时,也可以指定用于保存枚举值的底层数据类型.这些宏具有向后兼容能力,如果目标平台 ...

  2. iOS开发NS_ENUM和NS_OPTIONS区别

    OC里枚举的两种类型.NS_ENUM和NS_OPTIONS本质上是一样的都是枚举. typedef NS_ENUM(NSInteger, UIViewAnimationTransition) { UI ...

  3. NS_ENUM和NS_OPTIONS宏

    枚举的宏定义 一.简介  NS_ENUM和NS_OPTIONS宏提供了一种简明.简单的方法来定义基于C语言的枚举和选项. 这些宏提高了Xcode中的代码完成性,并明确指定了枚举和选项的类型和大小. 此 ...

  4. iOS: 枚举类型 enum,NS_ENUM,NS_OPTIONS

    一般情况下,我们采用C风格的enum关键字可以定义枚举类型. enum{ UIViewAnimationTransitionNone, UIViewAnimationTransitionFlipFro ...

  5. NS_ENUM & NS_OPTIONS

    When everything is an object, nothing is. So, there are a few ways you could parse that, but for the ...

  6. iOS/object-c: 枚举类型 enum,NS_ENUM,NS_OPTIONS

    一般情况下,我们采用C风格的enum关键字可以定义枚举类型. enum{ UIViewAnimationTransitionNone, UIViewAnimationTransitionFlipFro ...

  7. iOS中的枚举:enum, NS_ENUM, NS_OPTIONS的使用区别

    1.enum可以声明一般类型和位掩码(bitmasked)类型 例如: enum Test{// 一般枚举 TestA, TestB, TestC, }; enum{// 匿名枚举 TestA, Te ...

  8. Objective-C枚举的几种定义方式与使用

    假设我们需要表示网络连接状态,可以用下列枚举表示: enum CSConnectionState { CSConnectionStateDisconnected, CSConnectionStateC ...

  9. Objective-C开发编码规范【转载】

    概要 Objective-C是一门面向对象的动态编程语言,主要用于编写iOS和Mac应用程序.关于Objective-C的编码规范,苹果和谷歌都已经有很好的总结: Apple Coding Guide ...

随机推荐

  1. QTabWiget Remove Line Border 去除边框

    Qt中的QTabWiget 类提供了一个标签控件,但是这个控件默认是有边框的,如果我们不想要边框,也可以去掉这个边框,我们可以在cpp文件中添加一行代码: tabwidget.setStyleShee ...

  2. PCL Show Point Cloud 显示点云

    在使用PCL库的时候,经常需要显示点云,可以用下面这段代码: #include <pcl/visualization/cloud_viewer.h> pcl::PointCloud< ...

  3. [转] - MC、MC、MCMC简述

    贝叶斯集锦(3):从MC.MC到MCMC 2013-07-31 23:03:39 #####一份草稿 贝叶斯计算基础 一.从MC.MC到MCMC 斯坦福统计学教授Persi Diaconis是一位传奇 ...

  4. js 原生 ajax 异步上传图片

    <script type="text/javascript"> function upload() { var file1 = document.getElementB ...

  5. 汇编寄存器(内存访问)基础知识之三---mov指令

     1 内存中字的存储 一个字型数据占2个内存单元,内存里面一个内存单元一个字节(8位),高地址单位放高8位,低地址单元放低8位. 注意:0号是地址单元,1是高地址单元(上是低地址,下面是高地址) (1 ...

  6. html第一天

    html为超文本标记语言, html下的内容不去分大小写: 标签必须要有开始和结束,<br>和<hr>特殊,在标签内结束<br/>,<hr/>:下划线 ...

  7. Android课程---String、StringBuffer 、StringBuilder 的区别(转)

    String 字符串常量 StringBuffer 字符串变量(线程安全) StringBuilder 字符串变量(非线程安全)  简要的说, String 类型和 StringBuffer 类型的主 ...

  8. Solved Unable to copy the source file ./installer/services.sh to the destination file /etc/vmware-t

    Sometimes when you intall vmwaretools there will be some problems such as "Unable to copy the s ...

  9. bringSubviewToFront和insertSubview: atIndex:

    bring方法只能在当前SuperView中改变位置,insertSubview则可以脱离自己的superVIew,成为另个同级甚至高级的view的子view

  10. wp插件