iOS开发-之-位移枚举和按位或(|)按位与(&)运算

前言

Enumeration,enum,在程序设计语言中,一般用一个数值来代表某一状态,这种处理方法不直观,易读性差。如果能在程序中用自然语言中有相应含义的单词来代表某一状态,则程序就很容易阅读和理解。也就是说,事先考虑到某一变量可能取的值,尽量用自然语言中含义清楚的单词来表示它的每一个值,这种方法称为枚举方法,用这种方法定义的类型称枚举类型。

命名

定义的枚举类型名称通常与项目的类文件前缀相同,或者是类库框架缩写,或者跟随具体业务名,如果开头是缩写要大写表示,跟随其后的命名应采用驼峰命名法则,命名应准确表述枚举表示的意义,枚举中各个值都应以定义的枚举类型开头,其后跟随各个枚举值对应的状态、选项或者状态码

状态与选项(states and options)

状态
同时只能有一种,如“RecordPause”,“RecordEnd”,不可能同时Record是RecordPause和RecordEnd。如下:

typedef NS_ENUM(NSUInteger, VoiceRecordStatus){
    VoiceRecordStatusPrepare = 0,
    VoiceRecordStatusIng,
    VoiceRecordStatusPause,
    VoiceRecordStatusEnd
};

由于每种状态都用一个便于理解的值来表示,所以这样写出来的代码更易读懂。编译器会为枚举分配一个独有的编号,从0开始,每个枚举递增1

选项

定义选项的时候。若这些选项可以彼此组合,则更应如此。只要枚举定义得对,各选项之间就可通过“按位或操作符”(bitwise OR operator)来组合。例如,iOS UI框架中有如下枚举类型,用来表示某个视图应该如何在水平或垂直方向上调整大小

位移枚举(可复选的枚举) 使用位移实现选项变量

本文使用 Autoresizing 的系统枚举UIViewAutoresizing作为基础进行讲述:

以下位移已经提前计算出来了二进制与十进制值为了方便下文使用

typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing){    二进制值    十进制
    UIViewAutoresizingNone                  = 0,       00000000    0
    UIViewAutoresizingFlexibleLeftMargin    = 1<<0,    00000001    1
    UIViewAutoresizingFlexibleWidth         = 1<<1,    00000010    2
    UIViewAutoresizingFlexibleRightMargin   = 1<<2,    00000100    4
    UIViewAutoresizingFlexibleTopMargin     = 1<<3,    00001000    8
    UIViewAutoresizingFlexibleHeight        = 1<<4,    00010000    16
    UIViewAutoresizingFlexibleBottomMargin  = 1<<5     00100000    32
};

使用枚举定义选项,每个选项均可启用或禁用,使用上述方式来定义枚举值,每个枚举值所对应的二进制表示中,只有1个二进制位的值是1。用“按位或操作符”可组合多个选项

用( | )来隔开

aView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin;

而且每一个枚举对应的逻辑都会覆盖到

实例

- (void)todo:(UIViewAutoresizing)type {
    if (type == 0){
        NSLog(@"UIViewAutoresizingNone");
        return;
    }
    if (type & UIViewAutoresizingFlexibleLeftMargin){
        NSLog(@"UIViewAutoresizingFlexibleLeftMargin");
    }
    if (type & UIViewAutoresizingFlexibleWidth){
        NSLog(@"UIViewAutoresizingFlexibleWidth");
    }
    if (type & UIViewAutoresizingFlexibleRightMargin){
        NSLog(@"UIViewAutoresizingFlexibleRightMargin");
    }
    if (type & UIViewAutoresizingFlexibleTopMargin){
        NSLog(@"UIViewAutoresizingFlexibleTopMargin");
    }
    if (type & UIViewAutoresizingFlexibleHeight){
        NSLog(@"UIViewAutoresizingFlexibleHeight");
    }
    if (type & UIViewAutoresizingFlexibleBottomMargin){
        NSLog(@"UIViewAutoresizingFlexibleBottomMargin");
    }
}
- (void)viewDidLoad {
    [superviewDidLoad];
    //Do any additional setup after loading the view, typically from anib.
    [selftodo:UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleHeight];
}
结果输出
UIViewAutoresizingFlexibleLeftMarginUIViewAutoresizingFlexibleRightMarginUIViewAutoresizingFlexibleHeight

二进制转十进制

1101(2进制)= 1x20+0x21+1x22+1x23=1+0+4+8=13转化成十进制要从右到左用二进制的每个数去乘以2的相应次方不过次方要从0开始

位移位运算

如 UIViewAutoresizingFlexibleHeight = 1 << 4,

1.左移运算 1 << 4
将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)。
1 转化为二进制为 :0000 0001
左移四位就为 :0001 0000
0001 0000 转化为十进制等于16

2.右移运算 90>>4
将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。操作数每右移一位,相当于该数除以2。
90转化为二进制为 :01011010
右移4位就是 :00000101
00000101 转化为十进制等于5

按位或运算符(|)

运算规则:0|0=0; 0|1=1; 1|0=1; 1|1=1;
即 :参加运算的两个二进制对应数位只要有一个为1,其值为1

例如:
[self todo:UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleHeight];

1.十进制1|4|16 转为二进制0000 0001 | 0000 0100 | 0001 0000 = 0001 0101,因此,1|4|16的十进制值得21

按位与运算符(&)

参加运算的两个数据,按二进制位进行“与”运算。
运算规则:0&0=0; 0&1=0; 1&0=0; 1&1=1;
即:两对应数位同时为“1”,结果才为“1”,否则为0

1.十进制3&5 转为二进制 0000 0011 & 0000 0101 = 0000 0001 因此,3&5的值得1

2.在iOS方法中的应用

- (void)todo:(UIViewAutoresizing)type {
   if (type & UIViewAutoresizingFlexibleLeftMargin) {
      NSLog(@"UIViewAutoresizingFlexibleLeftMargin");
   }
}
传入参数type 为 UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleHeight

上文知道结果是 0001 0101,十进制值得21
UIViewAutoresizingFlexibleRightMargin为4

0001 0101 & UIViewAutoresizingFlexibleRightMargin = 0001 0101 & 0000 0100 =21 & 4 = 4 
根据计算结果还是UIViewAutoresizingFlexibleRightMargin这个枚举
所以理论上更严谨的写法应该是:
if ((type & UIViewAutoresizingFlexibleRightMargin) == UIViewAutoresizingFlexibleRightMargin){
}

要点 引用自effective Objective-C 2.0

应该用枚举来表示状态机的状态、传递给方法的选项以及状态码等值,给这些值起个易懂的名字。

如果把传递给某个方法的选项表示为枚举类型,而多个选项又可同时使用,那么就将各选项值定义为2的幂,以便通过按位或操作将其组合起来。

用NS_ENUM与NS_OPTIONS宏来定义枚举类型,并指明其底层数据类型。这样做可以确保枚举是用开发者所选的底层数据类型实现出来的,而不会采用编译器所选的类型。

在处理枚举类型的switch语句中不要实现default分支。这样的话,加入新枚举之后,编译器就会提示开发者:switch语句并未处理所有枚举。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,376评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,126评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,966评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,432评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,519评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,792评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,933评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,701评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,143评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,488评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,626评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,292评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,896评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,742评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,324评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,494评论 2 348

推荐阅读更多精彩内容