资料没看全,先抓一点重点。
swift5程序升级上来一堆错误,主要源自更严格的并发机制。
简单一点就是按如下规则来写:
- 给类加上@MainActor,强制运行在主线程,据说6.2这是默认的,不需要写出来
- 给后台方法加上@concurrent,并发,强制后台运行,因为是强制的,就不需要判断当前是什么线程了
- 在@concurrent方法里用DispatchQueue.main来执行需要在主线程运行的代码
- nonisolated 非隔离 方法继承调用者线程(与之对应isolated 隔离)
说实话我更喜欢明确的线程+锁。
async和await
async指示方法是异步执行的,await指示此处需要等待异步方法返回的结果。如果异步方法可能抛出异常,可以用try await ...来捕获(do... try...catch结构)。
async let 常量名 = 异步方法,并发执行而不等待结果(常量下次被使用前会确认初始化完成),只能在方法内部使用,不能用于属性定义。连续多个async let会并发执行,返回结果的顺序不确定。
Task
异步任务。不支持并发的环境不能直接await,可以套在Task里面,Task{await...}
actor
actor相当于一个特殊的类,不可继承。actor的所有可变数据的访问默认都被隔离(猜测在独立线程),因此对于外部都是异步的,需要await
nonisolated
用于变量,非隔离的(无需使用在常量上,因为没有必要)
@globalActor和@MainActor
定义全局actor,可以通过“@actor名称”来使用,可以用在类、属性、方法、闭包上。MainAcotr是预定义的全局actor,隔离在主线程执行。
MainActor.run{}可以替代DispatchQueue.main.async/sync。