首页 > 代码库 > ios:关于枚举

ios:关于枚举

在计算机科学理论中,枚举是一个被命名的整型常数的集合。定义形式如下:

enum 枚举名{              标识符[=整型常数],              标识符[=整型常数],              ...              标识符[=整型常数],         } 枚举变量; 
内存空间上,enum是枚举型 union是共用体,成员共用一个变量缓冲区。它不参加内存的占用和释放,枚举定义的变量可直接使用,甚至不用初始化。
如果枚举没有初始化,则从第一个标识符开始,顺次赋给标识符0, 1, 2, ...。下面示例枚举中 n1,n2,n3,n4分别为0,1,2,3
enum NSInteger{n1, n2, n3, n4}x; 
但当枚举中的某个成员赋值后,其后的成员按依次 加1的规则确定其值。
enum NSInteger{    n1,    n2 = 0,    n3 = 10,    n4}x; 
上面枚举示例中,n1,n2,n3,m4 分别为0,0,10,11。
1. 枚举中每个成员(标识符)结束符是",", 不是";", 最后一个成员可省略 ","。
2. 初始化时可以赋负数,以后的标识符仍依次加1。
3. 枚举变量只能取枚举说明结构中的某个标识符常量,例如此时n4=11.

虽然枚举类型被定义为一个整型集合,但是我测试还是可以定义成字符串,声明如下:
typedef enum : NSUInteger { blackColor, redColor, yellowColor } ThreeColor;
但是用法与整型枚举有些区别,它不能像整型直接使用,直接输出永远是0,需要写一个方法进行转换你需要的字符串。
- (NSString*) colorConvertToString:(ThreeColor) aColor {    NSString *result = nil;        switch(aColor) {        case blackColor:            result = @"black";            break;        case redColor:            result = @"red";            break;        case yellowColor:            result = @"yellow";            break;                    default:            result = @"unknown";    }        return result;}打印结果:NSLog(@"%@",[self colorConvertToString:redColor]);red
但一直觉得字符串枚举没有什么意义,从来没有用过。

枚举还支持位运算,比如在UIView类里面看到这样的定义。
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};
1<<0,0表示不进行移位 1还是1;大于1的会进行移位所以十进制的值分别是
typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {    UIViewAutoresizingNone                 = 0,          //十进制,指定的位数,二进制    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,     //1,0,01    UIViewAutoresizingFlexibleWidth        = 1 << 1,     //2,1,10       转换成 十进制  2    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,     //4,2,100      转换成 十进制  4    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,     //8,3,1000     转换成 十进制  8    UIViewAutoresizingFlexibleHeight       = 1 << 4,     //16,4,10000   转换成 十进制  16    UIViewAutoresizingFlexibleBottomMargin = 1 << 5      //32,5,100000  转换成 十进制  32};
位运算的计算方式是将二进制转换成十进制,也就是说,枚举值里面存取的是 计算后的十进制值.但是注意字符串枚举不适用于位运算。

所以在代码中下面这样写是没有任何区别的。
    [UIButton buttonWithType:UIButtonTypeCustom];    [UIButton buttonWithType:0];
枚举之间还可以这样写:(UIApplication.h)
typedef NS_OPTIONS(NSUInteger, UIInterfaceOrientationMask) {    UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait),    UIInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft),    UIInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight),    UIInterfaceOrientationMaskPortraitUpsideDown = (1 << UIInterfaceOrientationPortraitUpsideDown),    UIInterfaceOrientationMaskLandscape = (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),    UIInterfaceOrientationMaskAll = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown),    UIInterfaceOrientationMaskAllButUpsideDown = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),};
有时候,常说枚举一个数组,这里枚举其实是遍历的意思。在ios中为我们提供了一个枚举的类。(NSEnumerator.h)
@protocol NSFastEnumeration- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id __unsafe_unretained [])buffer count:(NSUInteger)len;@end@interface NSEnumerator : NSObject <NSFastEnumeration>- (id)nextObject;@end@interface NSEnumerator (NSExtendedEnumerator)@property (readonly, copy) NSArray *allObjects;@end
集合类(如:NSArray、NSSet、NSDictionary等)均可获取到NSEnumerator, 该类是一个抽象类,没有用来创建实例的公有接口。NSEnumerator的nextObject方法可以遍历每个集合元素,结束返回nil,通过与while结合使用可遍历集合中所有项。
示例:
NSArray *anArray = // ... ;NSEnumerator *enumerator = [anArray objectEnumerator];id object;while ((object = [enumerator nextObject])) {    // do something with object...}
遍历数组每个索引处的对象,你可以编写一个0到[array count]的循环,而NSEnumerator用来描述这种集合迭代运算的方式。
通过objectEnumerator向数组请求枚举器,如果想从后向前浏览集合,可使用reverseObjectEnumerator方法。在获得枚举器后,可以开始一个while循环,每次循环都向这个枚举器请求它的下一个对象:nextObject。nextObject返回nil值时,循环结束。
也可以自定义枚举器,要实现快速枚举就必须实现NSFastEnumeration协议,也就是
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
并且覆盖nextObject方法。
 

ios:关于枚举