目前开发中常用的枚举有两种:NS_ENUM 和NS_OPTIONS 。
不做过多铺垫,我们单刀直入,直接讲二者区别和用法。
1、定义:
NS_ENUM:普通枚举 、NS_OPTIONS:位移枚举
2、语法形式:
NS_ENUM :
typedef NS_ENUM(NSInteger, NSWritingDirection) {
NSWritingDirectionNatural = 0,
NSWritingDirectionLeftToRight,
NSWritingDirectionRightToLeft
};
NS_OPTIONS :
typedef NS_OPTIONS(NSUInteger, UISwipeGestureRecognizerDirection) {
UISwipeGestureRecognizerDirectionNone = 0, //值为0
UISwipeGestureRecognizerDirectionRight = 1 << 0, //值为2的0次方
UISwipeGestureRecognizerDirectionLeft = 1 << 1, //值为2的1次方
UISwipeGestureRecognizerDirectionUp = 1 << 2, //值为2的2次方
UISwipeGestureRecognizerDirectionDown = 1 << 3 //值为2的3次方
};
**注意区别:通常来讲普通枚举使用的是NSIterger,而NS_OPTIONS使用NSUInterger。原因,感兴趣同学可自行查阅。
3、如何使用:
通常来讲当有多个枚举值同时存在时,可以使用NS_OPTIONS。
例如:
UISwipeGestureRecognizer *swipeGR = [[UISwipeGestureRecognizer alloc] init];
swipeGR.direction = UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight;
而NS_ENUM定义的枚举不能几个枚举项同时存在,只能选择其中一项。
4、位移枚举的运算:
//定义一个位移枚举
typedef NS_OPTIONS(NSUInteger, MyOption) {
MyOptionNone = 0, //二进制0000,十进制0
MyOption1 = 1 << 0, //0001,1
MyOption2 = 1 << 1, //0010,2
MyOption3 = 1 << 2, //0100,4
MyOption4 = 1 << 3, //1000,8
};
//使用:判断、总结、移除枚举值
//声明定义枚举变量
MyOption option = MyOption1 | MyOption2; //0001 | 0010 = 0011,3
//检查是否包含某选型
if ( option & MyOption3 ) { //0011 & 0100 = 0000 通过位或运算来判断是否包含
//包含MyOption3
}
else {
//不包含MyOption3
}
//增加选项:
option = option | MyOption4; //0011 | 1000 = 1011, 11
//减少选项
option = option & (~MyOption4); //1011 & (~1000) = 1011 & 0111 = 0011, 3
位移枚举是通过位或运算来实现:判断、增加、减少对应枚举值的
5、实际使用:SDWebImageDownloader中通过使用位移枚举提供多项可选操作。
if ((!cachedImage || options & SDWebImageRefreshCached) && (![self.delegate respondsToSelector:@selector(imageManager:shouldDownloadImageForURL:)] || [self.delegate imageManager:self shouldDownloadImageForURL:url])) {
if (cachedImage && options & SDWebImageRefreshCached) {
// If image was found in the cache but SDWebImageRefreshCached is provided, notify about the cached image
// AND try to re-download it in order to let a chance to NSURLCache to refresh it from server.
[self callCompletionBlockForOperation:weakOperation completion:completedBlock image:cachedImage data:cachedData error:nil cacheType:cacheType finished:YES url:url];
}
// download if no image or requested to refresh anyway, and download allowed by delegate
SDWebImageDownloaderOptions downloaderOptions = 0;
//NOTE:Haoyu - 判断options中是否包含SDWebImageLowPriority枚举项,如包含,则将SDWebImageDownloaderLowPriority枚举值添加到downloaderOptions中。
if (options & SDWebImageLowPriority) downloaderOptions |= SDWebImageDownloaderLowPriority;
if (options & SDWebImageProgressiveDownload) downloaderOptions |= SDWebImageDownloaderProgressiveDownload;
if (options & SDWebImageRefreshCached) downloaderOptions |= SDWebImageDownloaderUseNSURLCache;
if (options & SDWebImageContinueInBackground) downloaderOptions |= SDWebImageDownloaderContinueInBackground;
if (options & SDWebImageHandleCookies) downloaderOptions |= SDWebImageDownloaderHandleCookies;
if (options & SDWebImageAllowInvalidSSLCertificates) downloaderOptions |= SDWebImageDownloaderAllowInvalidSSLCertificates;
if (options & SDWebImageHighPriority) downloaderOptions |= SDWebImageDownloaderHighPriority;
if (options & SDWebImageScaleDownLargeImages) downloaderOptions |= SDWebImageDownloaderScaleDownLargeImages;
if (cachedImage && options & SDWebImageRefreshCached) {
// force progressive off if image already cached but forced refreshing 移除某项枚举值
downloaderOptions &= ~SDWebImageDownloaderProgressiveDownload;
// ignore image read from NSURLCache if image if cached but force refreshing
downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse;
}
注:上述代码中用到了:|= 和 &= ~ ,二者分别等价于:options = options | SDWebImageDownloader
和 options = options & ( ~SDWebImageDownloader)
6、总结:
两种方式同为枚举,根据不同需求,我么可以分别采用不同的枚举。二者都较为常见,但通常来讲大家只会用NS_ENUM方式,对NS_OPTIONS会陌生一些,在阅读源码时,我们经常会遇到NS_OPTIONS这种枚举方式。而且很有用,所以需要掌握该部分知识点。
网友评论