枚舉enum、NS_ENUM 、NS_OPTIONS

enum

瞭解位移枚舉之前,我們先回顧一下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 enum A {
    a =
0,
    b,
    c,
    d,
} englishWord;

typedef enum {
    e =
4,
    f,
    g,
} englishWord2;

englishWord eg1 = a;
englishWord2 eg2 = e;

// enum newNum:NSInteger枚舉變量,並且繼承NSInteger;englishWord3 枚舉的別名
typedef enum newNum:NSInteger englishWord3;
enum newNum:NSInteger {
    new1 =
10,
    new2,
};
englishWord3 eg3 = new1;
eg1 = 0,eg2 = 4, eg3 = 10

2、NS_ENUM 、NS_OPTIONS

OC中常見的枚舉,例如常見的:

typedef NS_ENUM(NSInteger, UIViewAnimationCurve) {

UIViewAnimationCurveEaseInOut,         // slow at beginning and end

UIViewAnimationCurveEaseIn,            // slow at beginning

UIViewAnimationCurveEaseOut,           // slow at end

UIViewAnimationCurveLinear

};

typedef NS_OPTIONS(NSUInteger, UIViewAnimationOptions) {

UIViewAnimationOptionLayoutSubviews            = 1 <<  0,

UIViewAnimationOptionAllowUserInteraction      = 1 <<  1, // turn on user interaction while animating

UIViewAnimationOptionBeginFromCurrentState     = 1 <<  2, // start all views from current value, not initial value

UIViewAnimationOptionRepeat                    = 1 <<  3, // repeat animation indefinitely

UIViewAnimationOptionAutoreverse               = 1 <<  4, // if repeat, run animation back and forth

UIViewAnimationOptionOverrideInheritedDuration = 1 <<  5, // ignore nested duration

UIViewAnimationOptionOverrideInheritedCurve    = 1 <<  6, // ignore nested curve

UIViewAnimationOptionAllowAnimatedContent      = 1 <<  7, // animate contents (applies to transitions only)

UIViewAnimationOptionShowHideTransitionViews   = 1 <<  8, // flip to/from hidden state instead of adding/removing

UIViewAnimationOptionOverrideInheritedOptions  = 1 <<  9, // do not inherit any options or animation type

UIViewAnimationOptionCurveEaseInOut            = 0 << 16, // default

UIViewAnimationOptionCurveEaseIn               = 1 << 16,

UIViewAnimationOptionCurveEaseOut              = 2 << 16,

UIViewAnimationOptionCurveLinear               = 3 << 16,

UIViewAnimationOptionTransitionNone            = 0 << 20, // default

UIViewAnimationOptionTransitionFlipFromLeft    = 1 << 20,

UIViewAnimationOptionTransitionFlipFromRight   = 2 << 20,

UIViewAnimationOptionTransitionCurlUp          = 3 << 20,

UIViewAnimationOptionTransitionCurlDown        = 4 << 20,

UIViewAnimationOptionTransitionCrossDissolve   = 5 << 20,

UIViewAnimationOptionTransitionFlipFromTop     = 6 << 20,

UIViewAnimationOptionTransitionFlipFromBottom  = 7 << 20,

} NS_ENUM_AVAILABLE_IOS(4_0);

 

這兩個宏的定義在Foundation.framework的NSObjCRuntime.h中:

#if (__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && __has_feature(objc_fixed_enum))

#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type

#if (__cplusplus)

#define NS_OPTIONS(_type, _name) _type _name; enum : _type

#else

#define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type

#endif

#else

#define NS_ENUM(_type, _name) _type _name; enum

#define NS_OPTIONS(_type, _name) _type _name; enum

#endif


 
typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {
展開得到:
  1. typedef enum UIViewAnimationTransition : NSInteger UIViewAnimationTransition;  
  2. enum UIViewAnimationTransition : NSInteger {

其實從枚舉定義來看,NS_ENUM和NS_OPTIONS本質是一樣的,僅僅從字面上來區分其用途。NS_ENUM是通用情況,NS_OPTIONS一般用來定義具有位移操作或特點的情況(bitmask)。

開發中,你也許見到過或用過類似這種的枚舉類型:
typedef NS_OPTIONS(NSUInteger, BDRequestOptions) {
    BDRequestOptionSuccess     1 << 0,
    BDRequestOptionFailure     
1 << 1,
    BDRequestOptionProcessing 
1 << 2,
    BDRequestOptionAnimate     
1 << 3,
};

其實這種的並不是枚舉,而是按位掩碼(bitmask),他的語法和枚舉相同。但用法卻不同。

示例:

// 首先定義一組
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];

 

 

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等!
發佈了25 篇原創文章 · 獲贊 3 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章