Tino又想吃肉了

What's new in Swift5.5

Word count: 1.1kReading time: 4 min
2021/06/15

WWDC 2021学习记录第一篇,后续陆续更新

What’s new in swift 5.5
1) async/await

  • 几个概念:
  • 并发Concurrency/顺次Sequential并发中两个任务队列可以交替执行,在一个CPU时间片中A执行自己的任务并在用完时间片后将CPU使用权交给B。本质上仍然是单线程作业,只不过由于CPU时间片很短,在宏观角度上显示出来类似并行的效果。顺次则是两个任务队列只能先执行完一个再接着执行另外一个。
  • 并行Parallelism/串行Serialism并行相当于CPU的多个核心可以同时运算,串行则相当于CPU只有一个核心。而当一个设备同时支持并发和并行时,则CPU的利用率可以达到非常高的程度。在这种情况下每个核心对应的任务队列都可以交替进行,并且每个核心之间任务是同时进行的。
  • 数据竞争Data Race:并发计算中由于两个队列可以同时争夺一组资源,所以他们之间形成了数据竞争的关系,从而可能获取到错误或者无用的数据。例子:两个队列并发可乐机打可乐,可乐机由可乐糖浆和苏打水混合而成,这样的话可能一个队列取到糖浆另一个取到苏打水,他们都没有拿到正确有效的数据
  • 目标:并发,并行,没竞争或者保证数据安全。 (加锁)
  • Swift5.5的并发模型:1.以异步函数为中心 2.以结构化任务和数据隔离为基本点
  • async/await: async只是标记某个函数可以被await而已,告诉了编译器该函数在一定时间后可能会调用某个函数。async/await本质上只是替代了传统的completionHandler调用完成后函数的方法。在代码上减少了大量花括号,逻辑更直观。现在我们可以通过async/await用同步的思维来编写异步代码。被async标记的函数表示该函数可能会存在异步,也就是任务运行在global线程的情况。而await则意味着该函数可以放弃当前线程。
  • 结构化并发:使用withTaskGroupAPI可以创建一个async的任务组上下文,由于该上下文本身就是被async标记的,所以我们在创建的时候要await该上下文。在创建之后我们就可以使用group.async等派发函数向上下文中派发任务并执行。let _ = await withTaskGroup(of: Class.Type) { group -> Class.Type in group.async{} }
  • 更方便的API写法: 在swift5.5中我们可以直接将某个变量异步地绑定到我们的函数上。这就是函数式编程(Functional Programming)的思想,函数是一等公民,函数也可以是变量。那么之后我们只需要await该变量就可以得到函数执行的结果。[此处有图片]
  • 传统的在并发模型中保证数据的线程安全问题的方法:抽象出一个数据类,在数据类中定义一个串行队列,并将对数据的操作都派发到这个串行队列中同步执行,这样子避免了多个线程之间对数据的争抢。
    [此处有图片]
  • Task:在比较早的swift5.5版本中是以async{ ... }的方式创建一个异步的任务块,在Experiment版本的swift中该方法被废弃,由Task { ... }替代。
  • actor: 本质上是一个类,但是编译器会保证该类都运行在一个串行队列(DispatchQueue.sync)上(该类编译器帮我们封装了一个串行队列),保证线程安全。所以我们在取被actor修饰的类时我们要使用await关键词。同一个actor隔离,编译器保证同步访问。不同的actor隔离之间,编译器保证异步访问。
  • @MainActor:在开发UI时我们必须在主线程上操作我们的UI,通常我们需要使用GCD函数将任务派发到主线程上,使用MainActor关键词将保证其修饰的类或者函数始终运行在主线程。
  • @globalActor:使用@globalActor关键词修饰一个actor类可以自定义一个actor来修饰我们的类或者函数

2)Codable synthesis for enum

  • 带关联值的枚举在swift5.5中已支持Codable协议,编译器会自动合成encodedecode代码。

Tino Wu

CATALOG