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方法。

 
posted @ 2014-10-12 15:38  折半  阅读(749)  评论(0编辑  收藏  举报