如何使用 Swift 1.2 确定 NS_ENUM 的未记录值

How to determine if undocumented value for NS_ENUM with Swift 1.2

例如,下面NS_Enum定义...

typedef NS_ENUM(NSInteger, Type) {
  TypeNone = 0,
  TypeA = 1,
}
var x = 2
if let type: Type = Type(rawValue: x) {
  // Swift 1.2 executes this block.
}
else {
  // Previous swift executes this block.
}

如何确定 x 是否在 NS_ENUM 上定义?

假设 这是 Swift 1.2 中以下更改的结果,记录在 Xcode 6.3 release notes:

Imported NS_ENUM types with undocumented values, such as UIViewAnimationCurve, can now be converted from their raw integer values using the init(rawValue:) initializer without being reset to nil. Code that used unsafeBitCast as a workaround for this issue can be written to use the raw value initializer. For example:

let animationCurve =  
     unsafeBitCast(userInfo[UIKeyboardAnimationCurveUserInfoKey].integerValue,
     UIViewAnimationCurve.self)

can now be written instead as:

let animationCurve = UIViewAnimationCurve(rawValue:  
    userInfo[UIKeyboardAnimationCurveUserInfoKey].integerValue)!

问题(如果我理解正确的话)是

typedef NS_ENUM(NSInteger, UIViewAnimationCurve) { ... }

仅定义了 4 个可能的枚举值,但实际上可以采用其他枚举值 (未记录的)值也是如此。这使得一些讨厌的解决方法成为必要,例如

  • How to force a raw value of 7 into a UIViewAnimationCurve enum?

为了解决这个问题,Swift 1.2 现在允许创建 具有 任意 原始值的枚举变量(底层的 整数类型),如果枚举是从 NS_ENUM 定义.

因此,不可能以编程方式检查是否 "raw value" 是 NS_ENUM 定义中定义的值之一。

试试这个:

typedef NS_ENUM(NSInteger, Type) {
    TypeZero = 0,
    TypeOne = 1,
    TypeTwo = 2,
    TypeUnexpected = INT_MAX
};
switch Type(rawValue: 3) ?? .unexpected {
case .zero:
    // Handle type zero
    ...
case .one:
    // Handle type one
    ...
case .two:
    // Handle type two
    ...
default:
    // Handle unexpected types
    ...
}