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

SwiftUI中如何通过类的@State在结构体初始化@Binding?

SwiftUI中通过类初始化View的@Binding属性问题解决

首先得指出两个关键点:

  1. 你之前的“可编译代码”其实存在隐患:虽然编译器没报错,但class里用@State是完全错误的,它无法正确管理状态,修改junk值时不会触发View刷新,根本达不到你想要的效果。
  2. @State属性包装器只能用在值类型(比如View结构体)里,绝对不能用在引用类型的class中,这是SwiftUI的核心规则,也是导致你初始化代码失败的核心原因之一。

接下来我们一步步解决你的问题,让那段初始化代码能正常编译且正确运行:

第一步:修正你的JunkModel

根据你使用的iOS版本,有两种正确的写法:

写法一:iOS 13+ 兼容版本(使用ObservableObject + @Published)

我们需要让Model遵循ObservableObject协议,并用@Published标记需要监听的属性,这样SwiftUI才能感知到属性变化并刷新View:

import SwiftUI

class JunkModel: ObservableObject {
    @Published var junk = "xyz"
}

写法二:iOS 17+ 简化版本(使用@Observable)

如果你的项目已经升级到iOS17+,可以用新的@Observable宏来简化Model的写法,不需要手动遵循协议,SwiftUI会自动处理属性变化的监听:

import SwiftUI

@Observable class JunkModel {
    var junk = "xyz"
}

第二步:正确初始化View的@Binding属性

现在我们可以在View的初始化方法里,通过Model来创建合法的Binding实例,赋值给@Binding的底层存储属性_junk(注意是下划线开头的_junk,这是@Binding的实际存储变量):

对应iOS13+ Model的View写法

我们需要用Binding(get:set:)构造方法,通过闭包关联Model的junk属性,实现get和set逻辑:

struct Junk_Test: View {
    @Binding var junk: String
    
    init(model: JunkModel) {
        // 创建Binding,读取和修改都直接操作Model的junk属性
        self._junk = Binding(
            get: { model.junk },
            set: { model.junk = $0 }
        )
    }
    
    var body: some View {
        Text("\(junk)")
    }
}

对应iOS17+ Model的View写法

iOS17的@Observable宏给类的属性提供了直接的Binding投影,我们可以更简洁地完成初始化:

struct Junk_Test: View {
    @Binding var junk: String
    
    init(model: JunkModel) {
        // 直接使用@Observable提供的Binding投影,无需手动写get/set
        self._junk = $model.junk
    }
    
    var body: some View {
        Text("\(junk)")
    }
}

为什么原来的初始化代码无法编译?

  1. class中使用@State是非法的:@State的存储机制依赖于SwiftUI的View树,专门为结构体设计,class类型无法适配这种存储,所以你拿到的model.$junk本身就是一个不符合要求的对象。
  2. 错误操作了@Binding的投影属性:你尝试的$junk = model.$junk是错误的,$junk是@Binding的只读投影属性,我们不能直接赋值它,必须操作底层的_junk属性,并且传入一个合法的Binding实例。

现在你的预览代码可以保持不变,修改后的代码既能正常编译,又能正确实现状态管理的功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:03:30