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

SwiftUI中何时使用@State初始化@Observable对象?

结论:不要在@Observable类中使用@State

首先明确:@State是SwiftUI视图(View结构体)专用的属性包装器,绝对不能用在自定义的@Observable类里,你的第一种写法是错误的,编译或运行时都会出现不符合预期的问题。

两种写法的问题分析

  1. 带@State的写法:
    @State的设计初衷是让SwiftUI接管视图内部状态的存储和生命周期,它只能依附于View结构体。把它用在@Observable类中完全不符合其设计逻辑,不仅不会实现你想要的共享效果,还可能导致状态管理混乱。

  2. 不带@State的写法:
    这种写法本身是合法的,但如果你的需求是共享TaskRepository实例(比如多个ViewModel或视图共用同一个仓库数据),直接在CardViewModel里初始化TaskRepository()会导致每个CardViewModel实例都拥有独立的仓库,达不到共享目的。正确的做法是通过依赖注入,在创建CardViewModel时传入已有的TaskRepository实例:

    @Observable class CardViewModel{
        private let taskRepository: TaskRepository 
    
        var title: String = "Name"
        
        // 通过初始化方法注入仓库
        init(taskRepository: TaskRepository) {
            self.taskRepository = taskRepository
        }
        // 视图模型处理逻辑...
    }
    

    这样多个ViewModel就能共用同一个仓库实例,数据变化时所有关联的视图都会响应更新。

@State的正确适用场景

  • 仅用于SwiftUI View结构体内部:用来存储视图私有的、不需要跨视图共享的状态,比如开关的选中状态、输入框的临时文本、分页的当前页码等。
  • 管理值类型或轻量引用类型:比如Bool、String、Int等值类型,或者不需要跨视图传递的简单引用类型(比如本地的临时数据模型)。
  • 由SwiftUI托管生命周期:@State标记的状态会在视图重建时被SwiftUI保留,不会因为视图刷新而重置。

如果需要共享数据,推荐用这些方式:

  • 用@StateObject在View中创建全局/页面级的共享实例,再通过.environmentObject()注入环境,其他视图用@EnvironmentObject获取。
  • 通过依赖注入的方式,在初始化ViewModel或View时直接传递共享实例(耦合度更低,便于测试)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 13:07:07