NS_ENUM vs. NS_OPTIONS

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

时间: 2024-11-10 07:08:24

NS_ENUM vs. NS_OPTIONS的相关文章

iOS中特有的NS_ENUM和NS_OPTIONS

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

NS_ENUM和NS_OPTIONS

NS_ENUM 和 NS_OPTIONS 在iOS 6 / OS X Mountain Lion才开始有,他们都是用来代替 enum 的. 借用C的写法:只定义值,不定义类型 1 enum { 2  UITableViewCellStyleDefault, 3  UITableViewCellStyleValue1, 4  UITableViewCellStyleValue2, 5  UITableViewCellStyleSubtitle 6  }; 借用C的写法:定义值的同时定义类型 1 t

NS_ENUM 和 NS_OPTIONS的区别

在苹果的一篇官方文档<Adopting Modern Objective-C>"适应现代的Objectice-c"中提及到使用NS_ENUM和NS_OPTIONS来声明枚举 NS_ENUM用来声明基于一般整形的枚举,而NS_OPTIONS一般用来声明基于位掩码的声明(bitmask) 在一般的教程书中也经常提及,但是其中的区别是什么呢? 在NSObjCRuntime.h中有如下的宏定义 [cpp] view plain copy #define NS_ENUM(_type,

NS_ENUM &amp; NS_OPTIONS

一切皆为对象. 其实有很多种方式你可以在面向过程和面向对象间互相转化,但本文的目的是:有时候抛弃C层面的东西也是很好的. 是的——对于这种Smalltalk一样杂交而成的语言中的非面向对象部分而言,C语言是很有魅力的一部分.它速度快.久经考验,是现代计算最核心的部分.而且当面向对象范式处于过于庞大的设计而显得臃肿不堪的时候,C就变成了你的“安全出口”. 静态函数比硬要塞入类中的方法要好. 枚举比字符串常量要好. 按位掩码比字符串常量组成的数组要好. 过程化指令比runtime hack要好. 一

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

一般情况下,我们采用C风格的enum关键字可以定义枚举类型. [cpp] view plaincopy enum{ UIViewAnimationTransitionNone, UIViewAnimationTransitionFlipFromLeft, UIViewAnimationTransitionFlipFromRight, UIViewAnimationTransitionCurlUp, UIViewAnimationTransitionCurlDown, } UIViewAnimat

iOS - 枚举类型 enum,NS_ENUM,NS_OPTIONS

一般情况下,我们采用C风格的enum关键字可以定义枚举类型. enum{ UIViewAnimationTransitionNone, UIViewAnimationTransitionFlipFromLeft, UIViewAnimationTransitionFlipFromRight, UIViewAnimationTransitionCurlUp, UIViewAnimationTransitionCurlDown, } UIViewAnimationTransition; //位移操作

在 Swift 中实现 NS_OPTIONS

从Xcode 4.5以后,我们在Objective-C中使用NS_ENUM和NS_OPTIONS来定义一个枚举,以替代C语言枚举的定义方式.其中NS_ENUM用于定义普通的枚举,NS_OPTIONS用于定义选项类型的枚举. 而到了Swift中,枚举增加了更多的特性.它可以包含原始类型(不再局限于整型)以及相关值.正是由于这些原因,枚举在Swift中得到了更广泛的应用.在Foundation中,Objective-C中的NS_ENUM类型的枚举,都会自动转换成Swift中enum,并且更加精炼.以

NS_OPTIONS在swift中怎么实现?

今天在一个ios培训网站上看到一篇博客,讲的是在NS_OPTIONS在Swift中的实现,写得还算比较深刻全面,小编对其进行整理后,分享出来,希望对大家在iOS应用开发上有所帮助吧. 在iOS开发中,我们常常需要定义一个枚举,以替代C语言枚举的定义方式,常用的方法就是在Objective-C中使用NS_ENUM和NS_OPTIONS.其中,NS_ENUM用于定义普通的枚举,NS_OPTIONS用于定义选项类型的枚举. 不同于Objective-C语言,Swift中的枚举增加了更多特性,它可以包含

正确的使用枚举(Enum)

状态与选项的区别(states and options) 在用enum之前,我个人觉得,区分一下状态和选项的概念还是很必要的. 状态,同时只能有一种,如“OK”,“Error”,不可能同时是OK和Error.选项,同时可以有一种或一种以上,如App可以同时支持横屏和竖屏,横屏竖屏在这个时候就是“屏幕方向”的两种不同的选项. 接下来,我们看看如何用枚举定义状态和选项. enum与状态(states) typedef enum _TTGState { TTGStateOK = 0, TTGState