iOS 枚举的巧用

前言

在之前的一篇文章中简单的提到了这个问题, 但是自己写的不详细, 并且自己深入了解的也不是特别多, 在开发中也没怎么用到,所以经过阅读者的反馈对这个问题很是疑惑! 本篇文章会分析之前的不足之处, 如果有地方不对还请帮忙纠正!

相关文章: iOS开发中你是否遇到这些经验问题(二)

1.使用层面的理解

在这里首先讲如何简单的使用, 仅仅是使用层面(有理解错误的地方帮忙纠正), 然后我们在去理解位运算符! 在下面的图中我们可以看见枚举值中有<<(位运算符:左移):

如果我们在枚举值中看见<<那我们就可以通过|(位运算符:或)进行组合使用如下代码为例:

 //随便添加一个UITextField
 UITextField *field = [UITextField new];
 //Begin,Changed,DidEnd都能触发UITextField的事件
 [field addTarget:self action:@selector(textFieldDidChanged) forControlEvents: UIControlEventEditingDidBegin |
                  UIControlEventValueChanged |
                  UIControlEventEditingDidEnd
     ];

 [self.view addSubview:field];

如下图枚举值中没有<<,这就是普通的NSInteger类型的枚举, 所以不能组合使用:

那苹果官方是怎么知道我们多个条件组合使用了呢? 答案是通过&(位运算符:与)进行判断的:

//controlEvents是组合使用后的一个值
 NSUInteger controlEvents = UIControlEventEditingDidBegin | UIControlEventValueChanged | UIControlEventEditingDidEnd;
    /**
    //通过 & 来判断是否包含:
    UIControlEventEditingDidBegin,
    UIControlEventValueChanged,
    UIControlEventEditingDidEnd
     */
    if (controlEvents & UIControlEventEditingDidBegin) {

        NSLog(@"UIControlEventEditingDidBegin");

    }else if (controlEvents & UIControlEventValueChanged) {

        NSLog(@"UIControlEventValueChanged");

    }else if (controlEvents & UIControlEventEditingDidEnd) {

        NSLog(@"UIControlEventEditingDidEnd");
    }

那么我们接下来看看使用过程中牵扯到的位运算符, 我们会在下面举个例子!

2.理解位运算符

首先我们有一个枚举, 下面代码2种写法我们暂时先不用管,等位运算符讲完我们会讨论枚举的宏使用:

//typedef NS_OPTIONS(NSInteger, myTests) {
//    nameA = 1 << 0,
//    nameB = 1 << 1,
//    nameC = 1 << 2,
//    nameD = 1 << 3,
//};

typedef enum {
    nameA = 1 << 0,
    nameB = 1 << 1,
    nameC = 1 << 2,
    nameD = 1 << 3,

}myTests;

/**
 nameA = 1 << 0 :值为1(2的0次方)
 nameB = 1 << 1 :值为2(2的1次方)
 nameC = 1 << 2 :值为4(2的2次方)
 nameD = 1 << 3 :值为8(2的3次方)
 */

通过&进行判断我们来看看输出结果如下图:

我们得到NSInteger value = nameA | nameB;的组合的值, 判断结果是:1nameA的值, 2nameB的值, nameCnameD没有组合使用所以值为0,最后我们知道如果value & nameC0说明value不包含nameC 相反则包含!

还有一点就是value & nameA就是nameA的值为1, value & nameB就是nameB的值为2

  • <<(左移):a << b就表示把a转为二进制后左移b位(在后面添b0
  • |(或):只要有一个为1, 结果就是1
  • &(与):只要有二个为1, 结果才是1

我们已经知道nameA = 1, nameB = 2, nameC = 4, nameD = 8下面来通过二进制来解释:

 NSInteger value = nameA | nameB | nameC | nameD;
     转成二进制:
     nameA: 0 0 0 1
       |
     nameB: 0 0 1 0
       |
     nameC: 0 1 0 0
       |
     nameD: 1 0 0 0
    ----------------
     value: 1 1 1 1
     上面是使用 | 得出value的值为1111(|的意思是有一个为1结果就为1)

     下面是使用 & 判断输出的值(&的意思就是有二个为1结果才为1)

      value: 1 1 1 1         value: 1 1 1 1
        &                      &
      nameA: 0 0 0 1         nameB: 0 0 1 0
     ----------------       ----------------
      结果值: 0 0 0 1         结果值: 0 0 1 0

      我就写2个例子:0001就是nameA的值, 0010就是nameB的值

相信大家已经明白其中的道理了, 接下来我们来看看枚举的宏, 为了更好阅读也可以看下面的截图:

3.枚举的宏(NS_ENUMNS_OPTIONS)

NS_ENUMNS_OPTIONS宏提供了一个简洁、定义枚举和C语言选项的简单方法。

The NS_ENUM and NS_OPTIONS macros provide a concise, simple way of defining enumerations and options in C-based languages. These macros improve code completion in Xcode and explicitly specify the type and size of your enumerations and options. Additionally, this syntax declares enums in a way that is evaluated correctly by older compilers, and by newer ones that can interpret the underlying type information.

这是最初的使用方法:

enum {
        UITableViewCellStyleDefault,
        UITableViewCellStyleValue1,
        UITableViewCellStyleValue2,
        UITableViewCellStyleSubtitle
};
typedef NSInteger UITableViewCellStyle;

--------------------------------------------------

enum {
        UIViewAutoresizingNone                 = 0,
        UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
        UIViewAutoresizingFlexibleWidth        = 1 << 1,
        UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
        UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
        UIViewAutoresizingFlexibleHeight       = 1 << 4,
        UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
typedef NSUInteger UIViewAutoresizing;

通过使用枚举的宏:

NS_ENUM:是用来声明一般的NSInteger(下面代码使用NSInteger)类型的枚举

Use the NS_ENUM macro to define enumerations, a set of values that are mutually exclusive.

NS_OPTIONS:是用来声明位掩码(bitmasked)

Use the NS_OPTIONS macro to define options, a set of bitmasked values that may be combined together.

//NS_ENUM
typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
        UITableViewCellStyleDefault,
        UITableViewCellStyleValue1,
        UITableViewCellStyleValue2,
        UITableViewCellStyleSubtitle
};

--------------------------------------------------

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

NS_OPTIONSNS_ENUMenum 是有什么区别呢?

1.通过上面介绍我们可以看出enum可以声明一般类型和位掩码(bitmasked)类型

2.NS_ENUM声明一般类型, NS_OPTIONS声明掩码(bitmasked)类型

3.那么问题又来了, 直接用enum不就可以了? 答案不是这样的, 苹果建议我们在OC中使用NS_ENUMNS_OPTIONS, 为什么呢? 因为他们除了推断出不同类型的枚举,再就是当编译Objective-C++模式,它们产生的代码是不同的, 就是因为不同所以混编的时候使用enum会报错!

文/判若两人丶(简书作者)
原文链接:http://www.jianshu.com/p/97e582fe89f3
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

时间: 2024-11-02 07:26:25

iOS 枚举的巧用的相关文章

iOS 枚举类型学习

一,两者的用法 枚举类型定义用关键字enum标识,形式为: enum 标识符 { 枚举数据表 }:枚举数据(枚举常量)是一些特定的标识符,标识符代表什么含义,完全由程序员决定.数据枚举的顺序规定了枚举数据的序号,从0开始,依次递增.enum status{ copy, delete }:枚举类型status仅有两个数据,一个是copy,一个是delete,序号为0.1,代表复制与删除.enum status{ copy=6, delete }:则copy的序号为6,delete的序号为7.   

【Swift】ios开发中巧用 description 打印对象时,打印对象的属性

ios开发中我们打印对象的时候,会直接输出对象地址,这样不方便我们开发.我们可以 巧用 description 打印对象时,输出对象的属性 在oc中直接重写即可.swift中需要遵守Printable协议 看下面的例子 1 override var description: String { 2 let properties = ["属性1", "属性2", "属性3", "属性4"] 3 4 return "\(d

iOS枚举的运用

1.什么是枚举? 枚举其实就是一个整型常数的集合,最简单的例子就是表示星期的SUN, MON, TUE, WED, THU, FRI,SAT, 就是一个枚举. 2.iOS中枚举的使用 在ObjC中可以使用C语言的方式进行枚举,其实ObjC的枚举就是在C语言上演化而来,先了解C语言定义一个枚举的方式有助于我们对枚举的理解. 下面我们定义一个枚举类型Animal,形式为 enum 枚举名{ 枚举值表 };   我们在名为Animal的枚举中申明了多个成员名,我们可以看作是整形常量的别名.我们把cat

.Net下枚举的巧用

用户故事: 下图是系统中一组基于位运算的类别,其值分别为1,2,4,8,16.由于可以进行随意组合,所以落库值为[1,31]区间的任意值. 我们需要在页面上展示所有的组合,如下图: 如果使用if或者switch语句根据组合来输出组合对应的文本,那么就要写从[1,31]区间31种条件表达式,代码充斥着腐朽的味道.如果需求变动,再加几个类别的话...不好,是心肌梗塞的感觉: switch (rcType) { case 1: rcTypeDes = "低价RC"; break; case

ios 枚举 位移操作

引言: 枚举值 它是一个整形(int)  并且,它不参与内存的占用和释放,枚举定义变量即可直接使用,不用初始化. 在代码中使用枚举的目的只有一个,那就是增加代码的可读性. 使用: 枚举的定义如下: [csharp] view plaincopy typedef enum { //以下是枚举成员 TestA = 0, TestB, TestC, TestD }Test;//枚举名称 亦可以如下定义(推荐:结构比较清晰): [csharp] view plaincopy typedef NS_ENU

iOS - 枚举类型 enum,NS_ENUM,NS_OPTIONS

一般情况下,我们采用C风格的enum关键字可以定义枚举类型. enum{ UIViewAnimationTransitionNone, UIViewAnimationTransitionFlipFromLeft, UIViewAnimationTransitionFlipFromRight, UIViewAnimationTransitionCurlUp, UIViewAnimationTransitionCurlDown, } UIViewAnimationTransition; //位移操作

2016总结 wjwdive

2016 成长:收获最大的,学会了耐心,学会了宽容,学会了不强求.一念放下,万般自在.我真的是晚熟啊 ^_^! . 读书:<小王子>.<了不起的盖茨比>.<和任何人都聊得来>.<iOS进阶>-巧神.<iOS高级编程-多线程编程>.<effective Objective-C>.<精通iOS编程>.博客博文无数.... 技能:iOS,自认为是入门了.理论知识预备充足,但是缺乏实践.再加上互联网寒冬,iOS开发不像前几年那么火

React Native组件之ScrollView 和 StatusBar和TabBarIos

React Native中的组件ScrollView类似于iOS中的UIScrollView,其基本的使用方法和熟悉如下: /** * Sample React Native App * https://github.com/facebook/react-native * 周少停 ScrollView 的常用属性 * 2016-09-19 */ import React, { Component } from 'react'; import { AppRegistry, StyleSheet,

技能图谱

Gitbug地址: https://github.com/TeamStuQ/skill-map StuQ 程序员技能图谱 官网 Web 页面地址:http://skill-map.stuq.org/,也可扫描页面下方二维码,以赞助形式获赠技能图谱纸质版. 简介 StuQ 程序员技能图谱是由 StuQ(http://www.stuq.org/)发起的一个技术社区开源项目,志在汇集整理共建泛 IT 技术领域(人工智能,前端开发,移动开发,架构,云计算,大数据,运维,安全,后端开发,测试,智能硬件等)