位移枚举
了解位移枚举之前,我们先回顾一下C语言位运算符。
1 << : 左移,比如1<<n,表示1往左移n位,即数值大小2的n次方; 例如 : 0b0001 << 1 变为了 0b0010 2 >> : 右移,类似左移,数值大小除以2的n次方 3 & : 按位与,1与任意数等于任意数本身,0与任意数等于0,即1&x=x,0&x=0 4 | : 按位或,x|y中只要有一个1则结果为1;反之为0 5 ^ : 按位异或,x^y相等则为0,不等则为1
开发中,你也许见到过或用过类似这种的枚举类型:
typedef NS_OPTIONS(NSUInteger, BDRequestOptions) { BDRequestOptionSuccess = 1 << 0, // 1 BDRequestOptionFailure = 1 << 1, // 2 BDRequestOptionProcessing = 1 << 2, // 4 BDRequestOptionAnimate = 1 << 3, // 8 };
这种枚举类型,称之为按位掩码(bitmask),他的语法和枚举相同。
从枚举定义来看,NS_ENUM和NS_OPTIONS本质是一样的,而iOS使用两种方式定义的目的是区分使用场景 : 是否可以多选
NS_OPTION枚举 : 多个枚举值同时使用按位或( | )相加表示进行多选操作。位移不同位数得到值不同即数值代表的枚举值不同,多个枚举同时使用仍具有唯一性。
NS_ENUM枚举 : 不可多选,唯一互斥性。
示例:
// 首先定义一组 typedef NS_OPTIONS(NSUInteger, BDRequestOptions) { BDRequestOptionSuccess = 1 << 0, BDRequestOptionFailure = 1 << 1, BDRequestOptionProcessing = 1 << 2, BDRequestOptionAnimate = 1 << 3, }; // 然后调用我们定义的方法 #pragma mark - View lifeCycle - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor orangeColor]; [self test:BDRequestOptionSuccess | BDRequestOptionFailure | BDRequestOptionProcessing | BDRequestOptionAnimate]; } - (void)test:(BDRequestOptions)type { if (type & BDRequestOptionSuccess) { NSLog(@"BDRequestOptionSuccess"); } if (type & BDRequestOptionFailure) { NSLog(@"BDRequestOptionFailure"); } if (type & BDRequestOptionProcessing) { NSLog(@"BDRequestOptionProcessing"); } if (type & BDRequestOptionAnimate) { NSLog(@"BDRequestOptionAnimate"); } } // 查看打印结果: 2016-04-04 14:09:44.946 OC测试[5869:719056] BDRequestOptionSuccess 2016-04-04 14:09:44.947 OC测试[5869:719056] BDRequestOptionFailure 2016-04-04 14:09:44.947 OC测试[5869:719056] BDRequestOptionProcessing 2016-04-04 14:09:44.947 OC测试[5869:719056] BDRequestOptionAnimate
分析:
// 首先定义一组 typedef NS_OPTIONS(NSUInteger, BDRequestOptions) { BDRequestOptionSuccess = 0b0001 << 0, BDRequestOptionFailure = 0b0010 << 1, BDRequestOptionProcessing = 0b0100 << 2, BDRequestOptionAnimate = 0b1000 << 3, }; #pragma mark - View lifeCycle - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor orangeColor]; [self test:BDRequestOptionSuccess | BDRequestOptionFailure | BDRequestOptionProcessing | BDRequestOptionAnimate]; /** BDRequestOptionSuccess | BDRequestOptionFailure | BDRequestOptionProcessing | BDRequestOptionAnimate 等同于:0b0001 | 0b0010 | 0b0100 | 0b1000 结果为:0b1111 */ } - (void)test:(BDRequestOptions)type { // 0b1111 & 0b0001 ---> 0b0b0001 if (type & BDRequestOptionSuccess) { NSLog(@"BDRequestOptionSuccess"); } // 0b1111 & 0b0010 ---> 0b0b0010 if (type & BDRequestOptionFailure) { NSLog(@"BDRequestOptionFailure"); } // 0b1111 & 0b0100 ---> 0b0b0100 if (type & BDRequestOptionProcessing) { NSLog(@"BDRequestOptionProcessing"); } // 0b1111 & 0b1000 ---> 0b0b1000 if (type & BDRequestOptionAnimate) { NSLog(@"BDRequestOptionAnimate"); } }
另,默认的,如果开发中枚举值传0,意味着不做任何操作。
例如:
// 传0,不打印任何值 [self test:0];
具体用途:
// 以下所说的 0 或 1,均指二进制数字中的 0 或 1 // 1、赋值。 self.requestOption = BDRequestOptionSuccess | BDRequestOptionFailure | BDRequestOptionProcessing | BDRequestOptionAnimate; // 2、判断是否包含。 // &:按位与,1与任意数等于任意数本身,0与任意数等于0,即1&x=x,0&x=0 if (self.requestOption & BDRequestOptionSuccess) { NSLog(@"已包含了该枚举值"); } else { NSLog(@"不包含该枚举值"); } // 3、累加。 累加已经累加过的枚举值, 虽然枚举变量的值不会有变动,但这样将会误导阅读代码的人。 // |: 按位或,x|y中只要有一个1则结果为1;反之为0 self.requestOption |= BDRequestOptionSuccess; // 4、累减。 如果累减不存在的枚举值, 那么本次累减的枚举值,会自动累加上去。 // ^:按位异或,x^y相等则为0,不等则为1 self.requestOption ^= BDRequestOptionSuccess;
OC中的用法:
NSString *string = @"Learning"; [string boundingRectWithSize:CGSizeMake(CGRectGetWidth(self.view.frame), MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:12.f]} context:nil];
上面传值:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine
逻辑处理:
1 // 对传入的option逻辑处理 2 if (option & NSStringDrawingUsesLineFragmentOrigin) { 3 // 包含 NSStringDrawingUsesLineFragmentOrigin 4 } else { 5 // 未包含 NSStringDrawingUsesLineFragmentOrigin 6 } 7 if (option & NSStringDrawingTruncatesLastVisibleLine) { 8 // 包含 NSStringDrawingTruncatesLastVisibleLine 9 } else { 10 // 未包含 NSStringDrawingTruncatesLastVisibleLine 11 }
对于位移枚举的具体使用方法,建议可以查看一些三方库,例如SDWebImage等!
尊重作者劳动成果,转载请注明: 【kingdev】