swift Actor并发处理
nonisolated使用
在 Swift 并发编程中,nonisolated 是一个关键字,用于标记某个方法或属性不受 Actor 的隔离保护。这意味着被标记为 nonisolated 的成员可以在 Actor 外部直接访问,而无需通过 await 等待
nonisolated 通常用于以下场景:
访问不可变状态:如果某个属性是只读的且不会改变,可以将其标记为 nonisolated。
计算属性:如果某个计算属性不依赖于 Actor 的状态,可以将其标记为 nonisolated。
静态方法或属性:静态成员通常不依赖于 Actor 的实例状态,可以标记为 nonisolated。
actor MyActor{
private var counter:Int = 0
public func increment(){
counter += 1
}
/*
如果一个方法不访问 Actor 的状态,可以将其标记为 nonisolated
*/
nonisolated func getDescripter()->String{
return "This is MyActor"
}
/*
如果一个属性是只读的且不依赖于 Actor 的状态,可以将其标记为 nonisolated。
*/
nonisolated var descripter:String{
return "This is MyActor"
}
/*
如果计算属性不依赖于 Actor 的状态,可以将其标记为 nonisolated。
*/
nonisolated var isPositive:Bool{
return descripter.count > 0
}
private let id:UUID = UUID()
/*
如果 Actor 的某个属性是只读的且不会改变,可以将其标记为 nonisolated。
*/
nonisolated var uniquId:String{
return id.uuidString
}
/*
静态成员(属性和方法)通常不依赖于 Actor 的实例状态,可以标记为 nonisolated。
*/
nonisolated static let defaultname:String = "MyActor"
nonisolated static func getDefaultName()->String{
return defaultname
}
/*
不依赖于 Actor 状态的方法,可以标记为 nonisolated。
*/
nonisolated func print(){
Swift.print("Hello wrold")
}
}
func test1(){
let actor = MyActor()
print("\(actor.getDescripter())")
print("\(actor.descripter)")
Task {
await actor.increment()
}
}
MainActor使用
更新 UI:所有与 UI 相关的操作必须在主线程上执行。
访问主线程绑定的资源:例如 Core Data 的 NSManagedObjectContext(如果绑定到主线程)。
确保线程安全:避免在多线程环境中访问共享状态。
注意事项
性能:
过度使用 @MainActor 可能会导致主线程拥塞,影响 UI 响应性。确保只有必要的代码在主线程上运行。
死锁:
如果在 @MainActor 上下文中同步调用其他 @MainActor 方法,可能会导致死锁。避免在主线程上执行阻塞操作。
兼容性:
@MainActor 是 Swift 5.5 引入的特性,确保你的项目支持 Swift 并发编程。
/*
你可以将整个类型标记为 @MainActor,这样该类型的所有方法和属性都会在主线程上运行
*/
class DemoClass1{
}
/*
如果你只想让某个方法在主线程上运行,可以单独标记该方法。
*/
func updateUI(){}
/*
你也可以将属性标记为 @MainActor,以确保对该属性的访问和修改都在主线程上进行
*/
public var titleText:String?
/*
如果你需要在非 @MainActor 上下文中执行一段代码,可以使用 MainActor.run 来将代码切换到主线程
*/
func fetchData()async{
try? await Task.sleep(nanoseconds: 1000000000)
await MainActor.run {
print("run code in main thread")
}
}
/*
MainActor.assumeIsolated 是 Swift 并发编程中的一个工具,用于在编译时强制检查当前代码是否在 MainActor 上下文中执行。它可以帮助你在编写代码时明确要求某些操作必须在主线程上运行,从而避免潜在的多线程问题。
MainActor.assumeIsolated 适用于以下场景:
明确要求主线程执行:当你希望确保某段代码必须在主线程上运行时,可以使用 MainActor.assumeIsolated 来强制检查。
调试和验证:在调试时,你可以使用它来验证代码是否在主线程上运行。
避免潜在的多线程问题:通过强制检查,可以避免在非主线程上意外执行 UI 更新或其他主线程绑定的操作。
*/
func testd1(){
//主要用于调试,不会切换线程,如果不是主线程区块代码不会执行
MainActor.assumeIsolated {
print("run code in main thread")
}
// MainActor.shared;
}