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

为何在View.init()中设置代理无法更新SwiftUI的@State变量?

SwiftUI视图状态更新失效问题分析

问题代码

struct TestView: View {
    @State var text = "Hello"
    let useCase = TestUseCase()

    init() {
        useCase.output = self
    }

    var body: some View {
        Text(text)
            .onAppear {
                // ① useCase.output = self
                useCase.show()
            }
    }
}
extension TestView: TestUseCaseOutput {
    func showText(text: String) {
        self.text = text
    }
}

class TestUseCase {
    var output: TestUseCaseOutput?
    func show() {
        output?.showText(text: "Changed")
    }
}
protocol TestUseCaseOutput {
    func showText(text: String)
}

问题现象

代码意图在视图显示时将text从"Hello"改为"Changed",但实际运行时:

  • showText方法已被调用,但text的变更未反映到界面上
  • 若将useCase.output = self移到onAppear的①处,text能正常更新并同步到界面

原因解析

  • SwiftUI的视图是值类型(struct),SwiftUI会在视图状态变化时重新计算body,生成新的视图实例。
  • 在init中赋值的useCase.output = self,指向的是初始化阶段的旧视图实例;而onAppear执行时,界面上显示的是新的视图实例。当useCase回调showText时,修改的是旧实例的@State变量,自然无法触发当前界面的更新。
  • 把useCase.output = self放在onAppear中时,此时的self是当前显示在界面上的活跃视图实例,修改它的@State变量会触发SwiftUI的视图刷新逻辑,界面就能同步更新了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 03:32:14