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

初始化@State属性导致SwiftUI应用冻结,求问题排查方案

问题分析与解决方案

问题根源

应用挂起的核心原因是错误地用@State包装引用类型(ChildViewModel这个@Observable类),且手动初始化State的方式违反了SwiftUI状态管理规则:

  1. @State是为值类型设计的状态容器,负责值的持久化和视图刷新触发。而引用类型(类)实例存储在堆上,@State无法正确管理其生命周期,极易引发无限视图刷新循环,最终阻塞主线程导致应用挂起。
  2. 手动写_viewModel = State(initialValue: ChildViewModel())的初始化逻辑,干扰了SwiftUI内部的状态存储机制,触发了异常的视图更新流程。

修复方案

针对你的场景,有两种合规的实现方式:

方式1:用@StateObject管理Observable类(推荐)

因为ChildViewModel是@Observable类,应该使用@StateObject来包装——它专门负责管理引用类型Observable对象的生命周期:

struct ChildView: View {
    @StateObject private var viewModel = ChildViewModel()
    
    var body: some View {
        Text("Hello, World!")
    }
}
  • @StateObject会在视图初始化时创建唯一的ViewModel实例,并在整个视图生命周期内保持稳定,避免重复创建和异常刷新。
  • 无需手动编写init方法,SwiftUI会自动处理初始化逻辑。

方式2:改用值类型ViewModel(如果不需要Observable)

如果你的ViewModel不需要响应式能力(当前代码为空),可以将其改为结构体(值类型),再用@State包装:

struct ChildViewModel {
    // Empty
}

struct ChildView: View {
    @State private var viewModel = ChildViewModel()
    
    var body: some View {
        Text("Hello, World!")
    }
}

原代码挂起的具体原因

当用@State包装引用类型并手动初始化State时,SwiftUI的视图更新机制会陷入混乱:每次视图渲染时可能重复创建State实例,或者因引用类型的引用计数变化触发无限的视图刷新循环,最终导致主线程被完全阻塞,应用失去响应。移除ViewModel后,视图没有了异常的状态更新触发,自然恢复正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 01:29:55