Swift Concurrency 学习笔记 #127
zhangyu1818
announced in
zh-cn
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Swift 5.5里新增了Swift Concurrency,语法和Web前端里的异步非常之像,语法学习起来比较简单。
基本使用
关键词就是
async和await。不同的是需要放入Task里执行,并且一定需要加await关键字。另外一种是可以抛出错误的
async函数。调用会抛出错误的
async函数的时候需要使用try关键字。这样是不会输入任何结果的,因为已经抛出错误了,在这种情况需要用
do-catch语句。使用
do-catch可以捕获错误,另外还有2种try的修饰,try!和try?,可以不使用do-catch。try!是非常不建议使用的。try?在出现错误的时候会返回nil,在不需要捕获具体错误信息的时候非常有用。Task
Task接受一个闭包作为参数,返回一个实例。取消 Task
Task会返回实例,通过该实例的cancel()方法可取消任务。但是实际我们还是会输出"async function",只是跳过了等待2秒。
所以我们需要调用
Task.isCancelled或者Task.checkCancellation()来确保不再执行。Task的优先级
Task中有优先级的概念输出
优先级并不一定匹配,有时候会有优先级提升的情况。
子任务会继承父任务的优先级。
通过
Task.detached来分离任务。挂起Task
Task.yield()可以挂起当前任务。使用
Task.yield()。async let
await是阻塞的,意味着当前await函数在没执行完之前是不会执行下一行的。有些情况需要并行运行多个
async函数,这个时候则会用到async let。TaskGroup
如果任务过多,或者是循环里创建并行任务,
async let就不是那么得心应手了,这种情况我们应该使用withTaskGroup和withThrowingTaskGroup。of为子任务返回类型,在TaskGroup里我们也能通过group.cancelAll()和group.isCanceled配合来取消任务。Continuations
Continuations用于将以前的异步回调函数变成async函数,类似前端里的new Promise(resolve,reject)。现有以下代码
这段代码是通过
@escaping闭包的形式来获取结果,不能通过await获取,只需要使用withCheckedContinuation就可以将函数改造为async函数。除了
withCheckedContinuation,还有withCheckedThrowingContinuation可以抛出错误。actor
在很多语言里,都有线程锁这个概念,避免多个线程同一时间访问同一数据,造成错误。
Swift Concurrency里通过
actor来解决这个问题。actor里的属性和方法都是线程安全的。actor内默认属性和方法都是异步的,需要通过await来调用。如果需要某个方法不用
await调用,需要使用nonisolated关键字。MainActor
现有以下代码
当点击
Text两秒后会修改值。这时候会提示。因为UI改动都应该发生在主线程,可以使用老办法
Dispatch.main.async来解决。在Swift Concurrency里有多个方法。或者
也可以使用
@MainActor将方法或者类标记运行在主队列。SwiftUI中使用
SwiftUI中直接
.task修饰符即可。同时有一点比较好的是在
onDisappear的时候会自动取消Task。结语
作为初学者,Swift Concurrency简化了很多异步相关的问题,不需要再去使用闭包了,不会造成回调地狱,结合SwiftUI使用比Combine更简单友好,非常不错。‘
最近几天学习了这个,虽然我阳了,但是还是顶着发烧总结一晚上,以免烧完已经不记得了。
Beta Was this translation helpful? Give feedback.
All reactions