位移枚舉

瞭解位移枚舉以前,咱們先回顧一下C語言位運算符。git

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

開發中,你也許見到過或用過相似這種的枚舉類型:github

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使用兩種方式定義的目的是區分使用場景 : 是否能夠多選spa

NS_OPTION枚舉 :  多個枚舉值同時使用按位或( | )相加表示進行多選操做。位移不一樣位數獲得值不一樣即數值表明的枚舉值不一樣,多個枚舉同時使用仍具備惟一性。code

NS_ENUM枚舉   :  不可多選,惟一互斥性。blog

示例:開發

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

分析:get

// 首先定義一組
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,意味着不作任何操做。string

例如:it

// 傳0,不打印任何值
[self test:0];

 

具體用途:

// 如下所說的 0 或 1,均指二進制數字中的 0 或 1
    // 一、賦值。
    self.requestOption = BDRequestOptionSuccess | BDRequestOptionFailure | BDRequestOptionProcessing | BDRequestOptionAnimate;
    
    // 二、判斷是否包含。
    // &:按位與,1與任意數等於任意數自己,0與任意數等於0,即1&x=x,0&x=0
    if (self.requestOption & BDRequestOptionSuccess) {
        NSLog(@"已包含了該枚舉值");
    } else {
        NSLog(@"不包含該枚舉值");
    }
    
    // 三、累加。 累加已經累加過的枚舉值, 雖然枚舉變量的值不會有變更,但這樣將會誤導閱讀代碼的人。
    // |: 按位或,x|y中只要有一個1則結果爲1;反之爲0
    self.requestOption |= BDRequestOptionSuccess;
    
    // 四、累減。 若是累減不存在的枚舉值, 那麼本次累減的枚舉值,會自動累加上去。
    // ^:按位異或,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】

相關文章
相關標籤/搜索