这里每天分享一个 iOS 的新知识,快来关注我吧
前言
如果你的项目是 swift 语言写的,那么你一定遇到过类似这样的警告:
当我们点击 fix 自动修复,Xcode 会自动帮我们补全一个 @unknown default:
的语句:
我想很多人都见过这个场景,但是因为只是一个警告,所以没有多少人真正关心过这个是什么,今天就来讲一讲。
冻结枚举与非冻结枚举
先熟悉一下老知识,在传统的 Objective-C 和 C 中,枚举类型只是一个特定的整数列表,其中每个值都被赋予一个数字值。默认情况下,列表中的第一个元素设置为等于 0,并且为每个后续元素分配一个大 1 的值。
类似于这样:
objectivec
typedef NS_ENUM(NSInteger, UILayoutConstraintAxis) {
UILayoutConstraintAxisHorizontal = 0,
UILayoutConstraintAxisVertical = 1
};
在 OC 中这种用 NS_ENUM
关键字声明的枚举类型叫做非冻结枚举 ,意思是将来可以添加新的 case
,用 NS_CLOSED_ENUM
关键字声明的枚举类型叫做冻结枚举 ,以后不考虑新增 case
了,比如:
objectivec
typedef NS_CLOSED_ENUM(NSInteger, NSComparisonResult) {
NSOrderedAscending = -1L,
NSOrderedSame,
NSOrderedDescending
};
而在 swift 中用户定义枚举基本上都是冻结枚举。
对于非冻结枚举 来说,使用 switch
语句的时候,需要增加 @unknown default:
来做保底的处理,因为非冻结枚举未来还会继续增加 case
,系统希望你能尽可能的处理这种变化情况。
而对于冻结枚举 来说,未来不再打算增加新的 case
,所以不需要使用 @unknown default:
来处理。
default 和 @unknown default 的区别
相对 @unknown default
来说,大多数人做 swift 开发的同学应该更熟悉 default
。与 default
一样, @unknown default
也表示匹配其他任何值。
但不同的是,default
会兜住所有未被列举的 case,编译器也不会报警告,
但是如果使用 @unknown default
来兜底,如果有未列举的 case,编译器会给出一个警告:
@unknown default
还有种写法是 @unknown case _
效果是一样的。
swift
switch mode {
case .tile:
print("title")
case .stretch:
print("stretch")
@unknown case _: // 跟 @unknown default 一样
print("其他情况")
}
总结
iOS 中枚举分为冻结枚举和非冻结枚举,处理非冻结枚举时,需要用 @unknown default
或者 @unknown case _
来做兜底处理,否则编译器会报警告。如果直接使用 default
来兜底,那么当某个版本这个枚举有新增 case
时我们可能会导致异常情况。
今天分享了一个不是很有用的知识,但是知道总比不知道强,如果在一些面试中能答出这样的冷知识,也会是一个加分项。
这里每天分享一个 iOS 的新知识,快来关注我吧
本文同步自微信公众号 "iOS新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!