复选枚举(位移枚举)的实现逻辑

下面我们先来看看我们在开发中经常使用的苹果为我们提供的两个枚举值:

NS_ENUM

typedef NS_ENUM(NSInteger, UIButtonType) {
    UIButtonTypeCustom = 0,                         // no button type
    UIButtonTypeSystem NS_ENUM_AVAILABLE_IOS(7_0),  // standard system button

    UIButtonTypeDetailDisclosure,
    UIButtonTypeInfoLight,
    UIButtonTypeInfoDark,
    UIButtonTypeContactAdd,
    
    UIButtonTypePlain API_AVAILABLE(tvos(11.0)) API_UNAVAILABLE(ios, watchos), // standard system button without the blurred background view
    
    UIButtonTypeRoundedRect = UIButtonTypeSystem   // Deprecated, use UIButtonTypeSystem instead
};

该类型的枚举我们只能传递一个值,不能组合使用,比如:

UIButton *loginBtn = [UIButton buttonWithType:UIButtonTypeCustom];

关于这种枚举没有什么多说的,今天我们重点讨论的是下面的这种枚举以及实现方式

NS_OPTIONS

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
};

这种枚举与上面的不同,在使用的时候我们可以组合使用,传递多个值 比如:

self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleTopMargin;

那么不知道读者有没有想过这样一个问题,我们传递了多个数据,那么程序内部是如何去判断我们分别传递了那些值呢?

再具体的分析之前我们先来回忆一下 位运算的相关知识

|
如果两个相应的二进制位只要有一个是1,结果就是1;否则为0。
比如

  00000001
| 00000010
____________
  00000011

&
如果两个相应的二进制位都为1,则该位的结果值为1;否则为0。
比如

    00000011            00000011                           00000011 

  & 00000001          & 00000010   &上一个之前不包含的数据=> & 00000100
  ____________       ______________                     ______________
    00000001            00000010                           00000000

通过上面的运算我们可以看到 通过 & 运算之后可以得到它本身.
也就是如果e = a| b | c | d,那么e & a 、e & b 、e & c 、 e & d都为true.
就是说你这个枚举值包含了那些原始枚举值,&操作值都为true.否则为false

<<
向左移一位,右边自动补0
比如 1 << 1 = 2

  00000001 << 1

  00000010 = 2

所以通过上面的分析我们不难猜出位移枚举的内部判断逻辑应该是这样的:

- (void)setOptions:(UIViewAutoresizing)options
{
    if (options & UIViewAutoresizingFlexibleWidth) {
        NSLog(@"包含了UIViewAutoresizingFlexibleWidth");
    }
    
    if (options & UIViewAutoresizingFlexibleHeight) {
        NSLog(@"包含了UIViewAutoresizingFlexibleWidth");
    }
    
    if (options & UIViewAutoresizingFlexibleTopMargin) {
        NSLog(@"包含了UIViewAutoresizingFlexibleWidth");
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 一. 单例模式简介 单例模式的作用可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问从而方便地控...
    xx_cc阅读 50,310评论 15 146
  • 原链接:http://www.jianshu.com/p/4867dc92337e原作者:仅供我个人收藏学习,原博...
    油菜花花花花阅读 2,767评论 0 0
  • 单例模式作用 可以保证在程序运行过程中,一个类只有一个实例,而且该实例易于供外界使用 从而方便地控制了实例个数,并...
    珍此良辰阅读 5,152评论 3 8
  • 1 单例模式 它是一种设计模式(常见的设计模式有:观察者模式、工厂模式、门面模式等)。单例设计模式中,一个类只有一...
    岁与禾阅读 4,442评论 5 9
  • 已失效,大家看个思路就好 爬取原因:Python新手,就是想了解一下Python工程师在北上广等大中城市的薪资水平...
    Fretice阅读 8,603评论 13 11

友情链接更多精彩内容