NS_CLOSED_ENUM - ShenYj/ShenYj.github.io GitHub Wiki
用于声明不会变更枚举成员的简单的枚举(简称 “冻结枚举” ),对应 Swift 中的 @frozen
关键字,将作为 @frozen enum
导入到 Swift 中。冻结枚举对于希望在 switch
语句中匹配有限状态集的时候非常有用,这个有限状态集是一个完整的集合,覆盖了所有情况,将来不会再有其他新的情况。
例如,NSComparisonResult
枚举用于指定如何排序,在两个数比大小时,无非就 <、=、> 三种情况,所以非常适合使用冻结枚举。
// Declare in Objective-C
typedef NS_CLOSED_ENUM(NSInteger, NSComparisonResult) {
NSOrderedAscending = -1L,
NSOrderedSame,
NSOrderedDescending
};
// In Swift, the NSComparisonResult enumeration is imported like this:
@frozen enum NSComparisonResult : Int {
case orderedAscending = -1
case orderedSame = 0
case orderedDescending = 1
}
使用
NS_ENUM
和NS_CLOSED_ENUM
枚举宏在导入到 Swift 时生成的是实际enum
类型,而其它枚举宏都是生成struct
类型。
相比较于非冻结枚举,冻结枚举降低了灵活性,但提升了性能。一旦枚举被标记为冻结枚举,那么在未来版本的库中就不能通过添加、删除或重新排序枚举的 case,否则会破坏 ABI 兼容性。
-
对于非冻结枚举,你需要使用
default
或者@unknown default
来处理未知的 case(未来可能新增枚举类型),否则会得到编译器警告Switch covers known cases, but 'enumType' may have additional unknown values
,但 Xcode 的 fix 方案是使用@unknown default
-
而对于冻结枚举,使用
@unknown default
无论如何都会得到编译器警告(能运行)。-
如果你穷举了所有 case,将得到警告
Default will never be executed
,因为冻结枚举已经约定好将来不会添加新的枚举成员,所以@unknown default case
永远不会执行。虽然这里使用default
不会得到警告,但也是不会执行的 -
如果你没有穷举所有 case,将得到警告
Switch must be exhaustive
-> 使用@unknown default
必须穷举所有 case
-
-
对于冻结枚举,如果不希望穷举所有 case, 还是可以使用
default
,区别于@unknown default
, 不会得到编译警告
简单来说 default
和 @unknown default
都可以用来处理已知以及未知的情况。
区别在于,使用 @unknown default
,如果你没有穷举所有枚举类型,或者未来有新增枚举类型,那么编译器会给出警告提示。
对于非冻结枚举,如果你想穷举所有 case,并希望未来有新增枚举类型时得到编译器警告,那么就使用
@unknown default
。
也就是说,@unknown default
应该只匹配未来加入的枚举 case