Swift并发:在非隔离区域为何要使用被主Actor隔离的Sendable类型全局变量?
我已经启用易用的并发,默认隔离设为主(MainActor)。我这边有这段代码:
private let arc_total_degrees: CGFloat = 180 + 18
private let arc_start_degrees: CGFloat = 180 - 9
fileprivate struct MeterArcShape: Shape {
func path(in rect: CGRect) -> Path {
let radius = rect.width/2
var path = Path()
path.addArc(
center: CGPoint(x: radius, y: radius),
radius: radius,
startAngle: Angle(degrees: arc_start_degrees),
endAngle: Angle(degrees: arc_end_degrees),
clockwise: false)
return path
}
}
我收到了警告:
属于MainActor隔离的let 'arc_start_degrees' 不能在非隔离上下文中被引用
然而,CGFloat 应该是可发送的(Sendable),而我使用的是 let。这意味着不会产生数据竞争。为什么Swift会阻止我这么做?
我本可以对所有这些fileprivate全局变量使用 nonisolated,但数量太多,逐一标记很烦人。
解决方案
Sendable 不会移除actor隔离。CGFloat 是 Sendable,因此该值本身可以安全跨越并发域
但由于默认的actor隔离设置,该声明仍然是 MainActor-isolated。
Shape.path(in:) 是nonisolated,所以它不能同步访问一个属于MainActor隔离的全局常量
将该常量标记为 nonisolated,因为它只是一个静态值,不依赖于UI状态
你还可以把这些常量放在一个专用命名空间下,只对该命名空间标记为 nonisolated:
private nonisolated enum Constants {
static let arc_total_degrees: CGFloat = 180 + 18
static let arc_start_degrees: CGFloat = 180 - 9
static let arc_end_degrees: CGFloat = 180 + 9
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。