首页 > ios > 第5条:用枚举表示状态、选项、状态码(1)

第5条:用枚举表示状态、选项、状态码(1)

  由于Objective-C基于C语言,所以C语言有的功能它都有。其中之一就是枚举类型:enum。系统框架中频繁用到此类型,然而开发者容易忽视它。在以一系列常量来表示错误状态码或可组合的选项时,极宜使用枚举为其命名。由于C++11标准扩充了枚举的特性,所以最新版系统框架使用了“强类型”(strong type)的枚举。没错,Objective-C也能得益于C++11标准。
  枚举只是一种常量命名方式。某个对象所经历的各种状态就可以定义为一个简单的枚举集(enumeration set)。比如说,可以用下列枚举表示“套接字连接”(socket connection)的状态:

enum EOCConnectionState {  
    EOCConnectionStateDisconnected,  
    EOCConnectionStateConnecting,  
    EOCConnectionStateConnected,  
}; 

  由于每种状态都用一个便于理解的值来表示,所以这样写出来的代码更易读懂。编译器会为枚举分配一个独有的编号,从0开始,每个枚举递增1。实现枚举所用的数据类型取决于编译器,不过其二进制位(bit)的个数必须能完全表示下枚举编号才行。在前例中,由于最大编号是2,所以使用1个字节的char类型即可。
  然而定义枚举变量的方式却不太简洁,要依如下语法编写:

enum EOCConnectionState state = EOCConnectionStateDisconnected; 

  若是每次不用敲入enum而只需写EOCConnectionState就好了。要想这样做,则需使用typedef关键字重新定义枚举类型:

enum EOCConnectionState {  
    EOCConnectionStateDisconnected,  
    EOCConnectionStateConnecting,  
    EOCConnectionStateConnected,  
}; 
typedef enum EOCConnectionState EOCConnectionState; 

  现在可以用简写的EOCConnectionState来代替完整的enum EOCConnectionState了:

EOCConnectionState state = EOCConnectionStateDisconnected; 

  C++11标准修订了枚举的某些特性。其中一项改动是:可以指明用何种“底层数据类型”(underlying type)来保存枚举类型的变量。这样做的好处是,可以向前声明枚举变量了。若不指定底层数据类型,则无法向前声明枚举类型,因为编译器不清楚底层数据类型的大小,所以在用到此枚举类型时,也就不知道究竟该给变量分配多少空间。
  指定底层数据类型所用的语法是:

enum EOCConnectionStateConnectionState : NSInteger { /* ... */ };

  上面这行代码确保枚举的底层数据类型是NSInteger。也可以在向前声明时指定底层数据类型:

enum EOCConnectionStateConnectionState : NSInteger; 

  还可以不使用编译器所分配的序号,而是手工指定某个枚举成员所对应的值。语法如下:

enum EOCConnectionStateConnectionState {  
    EOCConnectionStateDisconnected = 1,  
    EOCConnectionStateConnecting,  
    EOCConnectionStateConnected,  
}; 

  上述代码把EOCConnectionStateDisconnected的值设为1,而不使用编译器所分配的0。如前所述,接下来几个枚举的值都会在上一个的基础上递增1。比如说,EOCConnectionState-Connected的值就是3。
  还有一种情况应该使用枚举类型,那就是定义选项的时候。若这些选项可以彼此组合,则更应如此。只要枚举定义得对,各选项之间就可通过“按位或操作符”(bitwise OR operator)来组合。例如,iOS UI框架中有如下枚举类型,用来表示某个视图应该如何在水平或垂直方向上调整大小:

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

  每个选项均可启用或禁用,使用上述方式来定义枚举值即可保证这一点,因为在每个枚举值所对应的二进制表示中,只有1个二进制位的值是1。用“按位或操作符”可组合多个选项,例如:UIViewAutoResizingFlexibleWidth| UIViewAutoresizingFlexibleHeight。图1-2列出了每个枚举成员的二进制值,并演示了刚才那两个枚举组合之后的值。用“按位与操作符”(bitwise AND operator)即可判断出是否已启用某个选项:

enum UIViewAutoresizing resizing =  
    UIViewAutoresizingFlexibleWidth |  
    UIViewAutoresizingFlexibleHeight;  
if (resizing & UIViewAutoresizingFlexibleWidth) {  
       // UIViewAutoresizingFlexibleWidth is set  
} 
  1. 还没有评论
评论提交中, 请稍候...

留言


可以使用的标签: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>
Trackbacks & Pingbacks ( 0 )
  1. 还没有 trackbacks