IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Swift 5.6 特性 -> 正文阅读

[移动开发]Swift 5.6 特性

Swift 5.6 特性

不可用条件(#unavailable)

#available 用于根据不同的平台、版本进行条件编译:

if #available(iOS 15, *) {
  // 通配符 * 表示 Apple 所有平台,如果是 iOS,则要求 >= 15
} else {
  // iOS 15 以下
}

Swift 5.6 引入了 #unavailable ,它和 #available 的意思正好相反,下面的示例和上面示例中的 else 分支表达的意思是一样的。

if #unavailable(iOS 15) {
  // iOS 15 以下
}

它也支持同时指定多个平台:

if #unavailable(iOS 15, macOS 12) {
  // iOS 15 以下, macOS 12 以下
}

注意:使用 #unavailable 使不需要通配符,我们的目的是为了使用它具体指出不可用的环境,使用 * 会造成歧义。

类型占位符(_、 _?)

Swift 5.6 支持使用占位符 __? 表示需要声明的类型,我们无需显示地指定类型,编译器会根据上下文自行推断。

let complexType: [Int: _] = [1: [1], 2: [[2]], 3: [(1, 2)], 4: [{}]]
// 编译器会将 complexType 的类型推断为 [Int : [Any]]

let complexType: [Int: _] = [1: [1], 2: [[2]], 3: [(1, 2)], 4: nil]
// 编译器会将 complexType 的类型推断为 [Int : [Any]?]

CodingKeyRepresentable 协议

我们想对字典进行编码,这个字典有点特殊,它的 key 是枚举类型。

enum AnimalType: String, Codable {
  case cat
  case dog
}

struct Animal: Codable {
  var name: String
  var age: String
}

let pets: [AnimalType: Animal] = [
  .cat: .init(name: "Mao", age: "3"),
  .dog: .init(name: "Biu", age: "2")
]
let petsData = try! JSONEncoder().encode(pets)
print(String(decoding: petsData, as: UTF8.self))
// print ["cat",{"name":"Mao","age":"3"},"dog",{"name":"Biu","age":"2"}]

打印的结果与预期不符,因为非 String/Int 类型的 key 值,Swift 在转换时无法正确处理。如果我们将这段编码后的字符串以 JSON 形式向服务端传参时,就会出现错误。为此,我们不得不做额外的工作来进行数据转换。

Swift 5.6 新增的 CodingKeyRepresentable 协议很好的解决了这个问题,它支持自定义 key 值的数据类型。我们让 AnimalType 遵循该协议,再次打印的结果与预期一致:

{"dog":{"name":"Biu","age":"2"},"cat":{"name":"Mao","age":"3"}}

any 关键字

any 和 Any、AnyObject、AnyClass 很像,但他们关系不大。Any 开头的一般表示的是擦除类型信息的类型,any 是一个关键字,用来修饰一种特殊的类型:存在类型(existential types)。

存在类型是一个比较抽象的概念,如果一定要给它下个定义,我会这样描述它:作为类型的协议。比如下面的代码

protocol UIMode {
  var color: Color { get set }
}

struct LightMode: UIMode {
  var color: Color = .white
}

struct DarkMode: UIMode {
  var color: Color = .black
}

struct ModeManager {
  var mode: UIMode
}

在 ModeManager 中 ,协议 UIMode 也被称作存在类型。我们使用一个 DarkMode() 实例来初始化 ModeManager 后,还可以使用 LightMode() 来替换原有的 mode。在编译期,mode 的类型是 UIMode。在运行时,mode 真正的类型是 LightMode、DarkMode 或其它任意遵循该协议的类型,它的值是可以动态分发的。

我们可以把存在类型的值想象成一个盒子,这个盒子可以动态地容纳所有符合该协议类型的值。只要是符合类型的值,相互之间可以动态替换。

我们将上面的代码结合泛型改造一下:

struct ModeManager<T: UIMode> {
  var mode: T
}

var manager = ModeManager(mode: DarkMode())
manager.mode = LightMode()

这段代码是无法通过编译的,因为我们在初始化 ModeManager 时传入的是 DarkMode 类型,泛型在编译层面就已经将 mode 约束成了 DarkMode 类型,当我们使用 LightMode 类型的值去改变 mode 时,编译器会报错。

通过对比我们可以看出,当协议作为类型时,它也可以被称为存在类型。如果协议作为泛型的约束,它就无法在运行时动态改变其类型,相应的值只能静态分发。另外,不透明类型中使用 some 关键字修饰的协议,也无法使用不同类型,它要求我们始终使用遵循该协议的特定类型。

动态虽好,但效率不及静态。存在类型带来了性能损耗,但它是我们常用的写法。因此 Swift 5.6 引入了 any 关键字,目的就是提醒我们存在类型的负面影响。同时,我们应该尽可能地避免使用 any。

struct ModeManager {
   var mode: any UIMode
}

从 Swift 6 开始,当我们使用存在类型时,编译器会强制要求使用 any 关键字标记,否则会报错。

前文我们提到过,Any 开头的类型一般是擦除类型信息的。它具有一定的动态特性,但会带来一定的性能损耗。这个规律在 SwiftUI 中也是适用的,SwiftUI 中的 AnyView 我们也要慎用。但也不能一概而论,比如 AnyPublisher 我们还是会用到。因此,到底要不要擦除类型信息来换取一定的灵活性,我们要在性能和灵活之间作一个较为平衡的选择。

以上.

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-04-09 18:32:44  更:2022-04-09 18:35:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 21:00:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码