我正在将代码更新到 Swift 6,并在从
awakeFromNib()
调用方法时遇到以下错误:
在同步非隔离上下文中调用主参与者隔离实例方法“addContentView()”;这是 Swift 6 语言模式下的错误
下面的代码定义了一个自定义
UIView
子类 SegmentedHeaderView
,它从 nib 文件加载其视图。我在 addContentView()
中调用 awakeFromNib()
来设置 UI。这是我的代码:
class SegmentedHeaderView: UIView {
@IBOutlet var contentView: UIView?
// Other IBOutlet properties
override func awakeFromNib() {
super.awakeFromNib()
addContentView() // Error occurs here
}
@MainActor
func addContentView() {
guard let view = loadViewFromNib() else { return }
view.frame = self.bounds
self.addSubview(view)
contentView = view
}
func loadViewFromNib() -> UIView? {
let nibName = "SegmentedHeaderView"
let bundle = Bundle(for: type(of: self))
let nib = UINib(nibName: nibName, bundle: bundle)
return nib.instantiate(withOwner: self, options: nil).first as? UIView
}
}
在 Swift 6 中,似乎
awakeFromNib()
被视为非隔离上下文,因此直接从它调用 @MainActor
函数会导致此错误。
使用
Task { @MainActor in ... }
:我将 addContentView()
包裹在 Task
中以确保它在主要参与者上运行,但这确实破坏了我的 UI。
override func awakeFromNib() {
super.awakeFromNib()
Task { @MainActor in
addContentView()
}
}
我也尝试过使用
MainActor.assumeIsolated
,似乎可以工作,但我不确定这是否是一个好的解决方案。
override func awakeFromNib() {
super.awakeFromNib()
MainActor.assumeIsolated {
addContentView()
}
}
使用
MainActor.assumeIsolated
是一个很好的解决方案,因为awakeFromNib
是一个UI相关的函数,所以它肯定会在主线程上运行