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

Apple SwiftUI教程中@Observable与@Environment宏报错的解决方法

SwiftUI @Observable & @Environment 错误解决

问题1:Unknown attribute 'ObservableObject'

原因

你混淆了SwiftUI两种响应式模型方案:

  • 新方案(iOS 17+/macOS 14+):用@Observable宏修饰类,无需额外协议或属性包装器。
  • 旧方案(iOS 13+):类遵循ObservableObject协议,用@Published标记需要监听的属性。

教程里用的是新宏,你大概率是误写了属性名(比如把@Observable写成了@ObservableObject),或者项目部署目标没升级到支持新宏的版本。

正确实现

  1. 确保项目部署目标设置为iOS 17+ / macOS 14+。
  2. 直接用@Observable修饰模型类:
@Observable
class ModelData {
    var landmarks: [Landmark] = load("landmarkData.json")
}

关于你之前的尝试

你用ObservableProtocol+@Published是旧的响应式写法,在iOS 17之前必须这么做,但新宏@Observable会自动追踪类中所有属性的变化,不需要手动加@Published,写法更简洁。


问题2:Cannot convert value of type 'ModelData.Type' to expected argument type 'KeyPath<EnvironmentValues, Value>'

原因

新的@Observable模型和@Environment的配合方式,和旧的@EnvironmentObject不同:

  • 旧方案用@EnvironmentObject直接注入遵循ObservableObject的实例。
  • 新方案需要给ModelData定义自定义环境键,再通过键路径注入/访问实例,你可能误传了ModelData类型而非实例,或者没定义环境键。

正确实现

  1. 定义自定义环境键和环境值扩展:
// 自定义环境键
private struct ModelDataKey: EnvironmentKey {
    static let defaultValue = ModelData()
}

// 给EnvironmentValues添加modelData属性
extension EnvironmentValues {
    var modelData: ModelData {
        get { self[ModelDataKey.self] }
        set { self[ModelDataKey.self] = newValue }
    }
}
  1. 在LandmarkList中通过@Environment访问:
struct LandmarkList: View {
    @Environment(\.modelData) var modelData
    // 后续可以直接用modelData.landmarks访问数据
    // ... 其他视图代码
}
  1. 在预览或根视图中注入实例:
struct LandmarkList_Previews: PreviewProvider {
    static var previews: some View {
        LandmarkList()
            .environment(\.modelData, ModelData()) // 传入的是ModelData实例,不是类型
    }
}

内容的提问来源于stack exchange,提问作者Michael-Andre Odusami

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 03:41:26