You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xcode 16.2 Beta 2中onPreferenceChange无法使用,Swift6下如何解决?

Swift 6模式下Xcode 16.2 Beta 2中onPreferenceChange的适配方案

问题场景

在Xcode 16.1中可正常运行的视图代码,在Xcode 16.2 Beta 2的Swift 6语言模式下,onPreferenceChange的闭包会抛出错误:"Main actor-isolated property 'height' can not be mutated from a Sendable closure"。

对比两个版本的onPreferenceChange签名差异:

  • Xcode 16.1签名:
@inlinable nonisolated public func onPreferenceChange<K>(_ key: K.Type = K.self, perform action: @escaping (K.Value) -> Void) -> some View where K : PreferenceKey, K.Value : Equatable
  • Xcode 16.2 Beta 2签名新增@Sendable修饰,但未添加@MainActor:
@inlinable nonisolated public func onPreferenceChange<K>(_ key: K.Type = K.self, perform action: @escaping @Sendable (K.Value) -> Void) -> some View where K : PreferenceKey, K.Value : Equatable

这种变化导致闭包无法直接修改Main Actor隔离的视图属性,尝试用Task包裹赋值操作还会触发**"EXC_BAD_ACCESS code=2"**崩溃:

.onPreferenceChange(HeightKey.self) { height in
  Task { @MainActor in
    self.height = height
  }
}

原视图代码:

struct HeightKey: PreferenceKey {
  static var defaultValue: CGFloat { .zero }
  
  static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
    value = nextValue()
  }
}

struct ContentView: View {
  @State private var height: CGFloat = 0
  
  var body: some View {
    VStack {
      Text("Title")
        .background(
          GeometryReader { proxy in
            Color.clear
              .preference(key: HeightKey.self, value: proxy.size.height)
          }
        )
        .onPreferenceChange(HeightKey.self) { height in
          self.height = height
        }
      
      Text("Height: \(height)")
    }
  }
}

可行适配方案

直接给onPreferenceChange的闭包添加@MainActor修饰,让闭包在Main Actor上下文执行,即可安全修改视图的@State属性,且不会触发崩溃:

.onPreferenceChange(HeightKey.self) { @MainActor height in
  self.height = height
}

也可以采用完整写法,将闭包整体标记为@MainActor:

.onPreferenceChange(HeightKey.self, perform: { @MainActor height in
  self.height = height
})

原理说明

@MainActor修饰的闭包会强制在主线程执行,既满足@Sendable的跨线程安全传递要求,又能合法访问Main Actor隔离的@State属性。

内容的提问来源于stack exchange,提问作者smr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 05:07:06