NS_ENUM与NS_OPTIONS

博客讨论了在Objective-C中NS_ENUM和NS_OPTIONS宏定义枚举的区别。虽然它们在输出结果上相似,但使用场景不同。NS_ENUM用于互斥的枚举类型,适合switch语句。而NS_OPTIONS用于位掩码,允许一个枚举变量表示多个值。文章建议根据枚举值的互斥性选择合适的宏,并提供了位掩码的概念链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在写代码的过程中我们会经常定义enum类型,这样做的好处是用enum关键字说明的常量由编译程序自动生成,我们不需要用手工对常量一一赋值,也增强了程序的可读性。但在OC中,苹果封装了这两个宏:NS_ENUM、NS_OPTIONS,又有什么区别呢?下面就一起试一下。

1、C语言类型的enum定义方式:

typedef enum : NSUInteger {
    name1 = 0,
    name2,
    name3,
    name4,
} NameType;


@interface Person : NSObject

@property(nonatomic,assign)NameType nameType;

@end
Person *person1 = [[Person alloc] init];

person1.nameType = name3;

if (person1.nameType & (name2 | name3)) {
    NSLog(@"nametype为2或3");
}

if (person1.nameType & (name3 | name4)) {
    NSLog(@"nametype为3或4");
}

输出结果为:

2017-03-06 18:33:36.247 TestProiect[72241:6511639] nametype为2或3
2017-03-06 18:33:36.247 TestProiect[72241:6511639] nametype为3或4

2、NS_ENUM定义方式:

typedef NS_ENUM(NSInteger,NameType){
    name1 = 0,
    name2,
    name3,
    name4,
};

输出结果为:

2017-03-06 18:39:03.505 TestProiect[72261:6516433] nametype为2或3
2017-03-06 18:39:03.506 TestProiect[72261:6516433] nametype为3或4

3、NS_OPTIONS定义方式,定义位掩码(Bitmask):

typedef NS_OPTIONS(NSInteger,NameType){
    name1 = 0,
    name2 = 1 << 0,         
    name3 = 1 << 1,
    name4 = 1 << 2,
};

输出结果为:

2017-03-06 18:41:00.804 TestProiect[72281:6518961] nametype为2或3
2017-03-06 18:41:00.804 TestProiect[72281:6518961] nametype为3或4

这样看起来这三种定义枚举类型的方式结果基本相同,那它们的区别是什么呢?

首先,enum是C语言方式的定义,在OC中苹果推荐我们尽量使用后两种方法来定义枚举。

关于NS_ENUM与NS_OPTIONS,我在stackOverflow上找到了这样的回答:What is the difference between NS_ENUM and NS_OPTIONS?

里面的最多赞同答案解释的很详细,首先:

There's a basic difference between an enum and a bitmask (option). You use an enum to list exclusive states. A bitmask is used when several properties can apply at the same time.

翻译过来就是:关于NS_ENUM与NS_OPTIONS的使用方式,一个最基本的原则:如果列举的类型之间是一种互斥的关系,那么用NS_ENUM;如果列举的类型之间没有明显的互斥关系,即一个枚举变量可能要同时代表多个枚举值,那么就用NS_OPTIONS

所以,我们在区别使用NS_ENUM定义的类型时可以使用switch语法,这样:

typedef NS_ENUM(NSInteger, MyStyle) {
    MyStyleDefault,
    MyStyleCustom
};


switch (style){
    case MyStyleDefault:
        // int is 0
    break;
    case MyStyleCustom:
        // int is 1
    break;
}

在区别使用NS_OPTIONS定义的类型时,因为NS_OPTIONS基于位掩码的声明,可以这样:

typedef NS_OPTIONS(NSInteger, MyOption) {
    MyOption1 = 1 << 0, // bits: 0001
    MyOption2 = 1 << 1, // bits: 0010
};

if (option & MyOption1){ // last bit is 1
    // bits are 0001 or 0011
}
if (option & MyOption2){ // second to last bit is 1
    // bits are 0010 or 0011
}
if ((option & MyOption1) && (option & MyOption2)){ // last two bits are 1
    // bits are 0011
}

最后可以用一句话概括:

An enum gives names to numbers. A bitmask gives names to bits. 

即一般来说NS_ENUM枚举的元素是整型,NS_OPTIONS枚举的元素是位掩码。

对于位掩码不了解的同学可以看下这里:iOS 枚举的巧用

PS:之所以加一个一般来说,是因为其实两者基本思想是没有区别的,据其根本,枚举的目的是为整型数据添加一个名字。NS_ENUM,NS_OPTIONS只是为了代码的统一性,约束一下编码规则罢了。

参考资料:
What is the difference between NS_ENUM and NS_OPTIONS?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值