枚举声明的类型是囊括可能状态的有限集。也可以说enum是一组常量的集合,可以让我们的代码可读性更高。
Enum in OC
OC中枚举类型必须为整型,默认第一个枚举值为0。
iOS6中引入了两个宏来定义枚举类型(即:NS_ENUM与NS_OPTIONS),这两者在本质上并没有差别,都是用于定义枚举类型,但是在使用中NS_ENUM多用于一般枚举,而NS_OPTIONS则多用于带有移位运算的枚举。
对于一般的枚举,要获取枚举的最大值是很难的,因为随着枚举的扩充,最大值在不断变化,这时推荐使用一个固定的枚举表示最大值。
typedef NS_ENUM(NSUInteger, EnumTest)
{
EnumTestOne,
EnumTestTwo,
EnumTestMax //Max Value
};
位枚举是一种特殊的枚举,位枚举可以使用位运算来处理枚举值,实际使用中可以用一个变量存储多个枚举值,表示互不影响的多个设置。
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
};
test |= TMEnumTestFour; //添加
test &= ~TMEnumTestThree; //移除
if (test & TMEnumTestFour) //是否包含
Enum in Swift
和OC中的枚举相比,Swift有三点优势:
- OC中,你只能为枚举分配整型值,而Swift则可以不用给每个枚举提供枚举值,同时枚举值类型可以是整型,浮点数,字符串,布尔类型, 让它使用起来更灵活;
- Enum可以通过关联值将额外信息附加到每个枚举, 这些关联值可以是任意类型;
- 通过内嵌(nesting),添加方法,关联值和模式匹配(pattern matching), 枚举可以分层次地定义任何有组织的数据,清晰表达代码的意图。
Enum在Swift的应用场景非常多:
-
Optional就是由 ENUM + 范型定义的一个数据类型;
可以通过递归枚举来定义如FileNode、二叉树等类型;
-
将字符串类型的重用标识或者 storyboard 标识映射为类型系统可以进行检查的类型;
Enum 还可以用来定义值类型model,说到定义值类型model, 通常会想到使用struct。来看个列子:
protocol ErrorType {
func description() -> String
}
enum APIError: ErrorType {
case PasswordIncorrect
case UserIsNotExist
case ConnectError(error: NSError)
func description() -> String {
switch self {
case .PasswordIncorrect:
return "password is not correct"
case .UserIsNotExist:
return "user is no exist"
case .ConnectError(let error):
return "connect error: \(error)"
}
}
}
struct PasswordIncorrect: ErrorType {
func description() -> String {
return "password is not correct"
}
}
struct UserIsNotExist: ErrorType {
func description() -> String {
return "user is no exist"
}
}
struct ConnectError: ErrorType {
func description() -> String {
return "connect error: \(error)"
}
let error: NSError
}
可以看出使用enum定义model有2个好处:
- 更清晰,知道有多少种类型的APIEorror;
- 预防将其他类型的error传递给api error 类型的参数,更安全。
所以一般来讲,如果问题可以被分解为有限的不同类别,则推荐使用来enum定义model 。