枚举&位移枚举
之前,我们一般都采用C语言的方式定义枚举,这种枚举可以称为普通的枚举。
typedef enum{
DirectionTypeUp,
DirectionTypeLeft,
DirectionTypeDown,
DirectionTypeRight
} DirectionType;
但是我们在查看苹果的SDK或者看一些第三方库时会像下面这样定义枚举。比如SDWebImage代码中这样定义枚举,这称为位移枚举。
typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) {
SDWebImageRetryFailed = 1 << 0,
SDWebImageLowPriority = 1 << 1,
SDWebImageCacheMemoryOnly = 1 << 2,
SDWebImageProgressiveDownload = 1 << 3,
SDWebImageRefreshCached = 1 << 4,
SDWebImageContinueInBackground = 1 << 5,
SDWebImageHandleCookies = 1 << 6,
SDWebImageAllowInvalidSSLCertificates = 1 << 7,
SDWebImageHighPriority = 1 << 8,
SDWebImageDelayPlaceholder = 1 << 9,
SDWebImageTransformAnimatedImage = 1 << 10,
};
这种“位移枚举”是代表什么意思那?? 先回顾一下位运算符号(具体细节请百度)
下面我结合实际应用,说明一下“位移枚举”。
#import "ViewController.h"
// 因为"位运算"的计算方式是将二进制转换成十进制,也就是说,枚举值里面存取的是计算后的十进制值.
typedef NS_OPTIONS(NSUInteger, DirectionType) {
DirectionTypeUp = 1 << 0, // 十进制1
DirectionTypeLeft = 1 << 1, // 十进制2
DirectionTypeDown = 1 << 2, // 十进制4
DirectionTypeRight = 1 << 3,// 十进制8
};
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self demoTest:DirectionTypeUp | DirectionTypeLeft | DirectionTypeRight];
/*
DirectionTypeUp 表示 0001
DirectionTypeLeft 表示 0010
DirectionTypeRight 表示 1000
按位或之后变成 1011 (十进制表示 11)
*/
}
- (void)demoTest:(DirectionType)options{
/*
因为这里options 表示 1011 ,然后进行按位与
*/
if (options & DirectionTypeUp) { // 1011 & 0001 按位与为 0001
NSLog(@"向上");
}
if (options & DirectionTypeLeft) { // 1011 & 0010 按位与为 0010
NSLog(@"向左");
}
if (options & DirectionTypeDown) { // 1011 & 0100 按位与为 0000
NSLog(@"向下");
}
if (options & DirectionTypeRight) { // 1011 & 1000 按位与为 1000
NSLog(@"向右");
}
/*
所以最后打印: 向上 向左 向右
*/
}
@end
其实,"位移枚举"是C语言中遗留下来的一种很古老并且好用的技术延用至今。只需要定义一个参数,就可以通过传入不同的枚举组合,达到我们想要的效果。所以苹果在iOS6和Mac OS 10.8以后引入了两个宏NS_OPTIONS 和NS_ENUM来定义枚举类型,实际上是将enum定义和typedef合二为一,NS_ENUM和NS_OPTIONS本质是一样的,仅仅从字面上来区分其用途,采用不同的宏来从代码角度来区分。我们可以参考UIKit.Framework的头文件,可以看到大量的枚举定义。
参考资料 : https://my.oschina.net/ioslighter/blog/409918
NS_OPTIONS :一般用来定义位移相关操作的枚举值。
NS_ENUM: 一般用来定义普通的枚举。
typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {
UIViewAnimationTransitionNone,//默认从0开始
UIViewAnimationTransitionFlipFromLeft,
UIViewAnimationTransitionFlipFromRight,
UIViewAnimationTransitionCurlUp,
UIViewAnimationTransitionCurlDown,
};
typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
UIViewAutoresizingNone = 0,
UIViewAutoresizingFlexibleLeftMargin = 1 << 0,
UIViewAutoresizingFlexibleWidth = 1 << 1,
UIViewAutoresizingFlexibleRightMargin = 1 << 2,
UIViewAutoresizingFlexibleTopMargin = 1 << 3,
UIViewAutoresizingFlexibleHeight = 1 << 4,
UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
参考资料 : https://my.oschina.net/ioslighter/blog/409918