讲讲 swift 中的冻结枚举和非冻结枚举

这里每天分享一个 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新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
黑化旺仔2 小时前
【OC】KVO
macos·ios·objective-c·cocoa
HouWan3 小时前
SwiftUI 小技巧:如何读取 SwiftUI Font 的详细信息
ios·swiftui·apple
李游Leo4 小时前
HarmonyOS 7 实战开发 05:把页面做到可上线状态
ios·harmonyos
终端安全笔记9 小时前
描述文件、企业证书、MDM 不是三个名字,是三层
android·ios·智能手机
传奇开心果编程10 小时前
【SwiftUI入门练中学】第1课 从零开始
学习·ui·ios·swiftui·swift
丿Wayne15 小时前
iOS Token 刷新实战(Actor 避免并发重复刷新)
ios·swift·token·actor·swift并发
终端安全笔记1 天前
iOS 27 给了租赁一个新工具,但它只认受监督的设备
android·网络·安全·ios
大熊猫侯佩1 天前
独立 App 首发完成 iPhone Duo 展开态适配
ios·swiftui·swift
光影少年2 天前
setImmediate 和 setTimeout(0) 的区别
android·前端·react.js·ios·前端框架
2501_916008892 天前
SSE 和 gRPC 流式接口如何抓包,调试 SSE 与 gRPC 流式接口
网络协议·计算机网络·网络安全·ios·adb·https·udp