SwiftUI 核心选型:class + ObservableObject VS struct + @State

SwiftUI 的状态管理,本质是数据驱动 UI。但在实际开发中,一个绕不开的问题是:

👉 到底该用 struct + @State,还是 class + ObservableObject

这不是语法选择,而是数据生命周期 + 共享方式的设计问题。


一句话结论

  • 局部、私有、短生命周期状态@State

  • 跨视图共享、可复用、可观察状态ObservableObject


1. @State:View 私有状态(值语义)

复制代码
struct CounterView: View {
    @State private var count = 0
    
    var body: some View {
        Button("\(count)") {
            count += 1
        }
    }
}

特点

  • 只能在当前 View 内使用

  • SwiftUI 持有并管理生命周期

  • 值类型(struct),更新即触发 View 重建

  • 不适合跨 View 传递

本质

@StateView 的本地状态缓存,SwiftUI 会在 View 重建时帮你"记住"它。

👉 可以理解为:"UI 内部状态"


2. ObservableObject:可共享状态(引用语义)

复制代码
class CounterModel: ObservableObject {
    @Published var count = 0
}

struct CounterView: View {
    @StateObject private var model = CounterModel()
    
    var body: some View {
        Button("\(model.count)") {
            model.count += 1
        }
    }
}

特点

  • 引用类型(class)

  • 多个 View 可以共享

  • @Published 自动触发 UI 更新

  • 生命周期由 @StateObject / @ObservedObject 控制

本质

👉 一个外部数据源(Source of Truth)


3. 核心差异对比

维度 @State ObservableObject
类型 struct(值) class(引用)
作用域 当前 View 多 View 共享
生命周期 SwiftUI 管理 你控制
数据传递 不支持 支持
适用场景 UI 状态 业务状态

4. 关键设计问题:谁拥有数据?

这是选型的核心。

✅ 用 @State 的情况

  • toggle / 输入框 / 动画状态

  • UI 层临时数据

  • 不需要跨组件

    @State private var isLoading = false

👉 View 自己拥有状态


✅ 用 ObservableObject 的情况

  • 用户信息

  • 网络请求结果

  • 跨页面数据共享

    class UserStore: ObservableObject {
    @Published var user: User?
    }

👉 状态独立于 View 存在


5. 常见误区

❌ 误区 1:所有状态都用 ObservableObject

问题:

  • 过度抽象

  • 性能变差(不必要的刷新)

  • 代码复杂

👉 UI 局部状态没必要上升为全局状态


❌ 误区 2:用 @State 管理复杂模型

复制代码
@State var user = User(...)

问题:

  • 数据难共享

  • 更新链条混乱

👉 复杂数据 = ObservableObject


❌ 误区 3:错误使用 @ObservedObject

复制代码
@ObservedObject var model = CounterModel() // ❌

问题:

  • View 重建 → model 被重建 → 状态丢失

👉 应该用:

复制代码
@StateObject private var model = CounterModel()

6. 进阶:组合使用(推荐)

实际项目中,一般是组合:

复制代码
struct ProfileView: View {
    @StateObject var userStore = UserStore()
    @State private var isEditing = false
}
  • userStore → 业务数据

  • isEditing → UI 状态

👉 分层清晰,职责明确


7. 设计哲学总结

  • @State:UI 的"感觉"

  • ObservableObject:业务的"事实"

或者更直接一点:

👉 View 应该轻,状态应该分层


8. 实战建议(工程视角)

  • 小组件优先 @State

  • 页面级数据用 @StateObject

  • 跨页面用 EnvironmentObject

  • 不要让 View 持有复杂业务逻辑


最后一句

SwiftUI 不是在问"用哪个",而是在问:

👉 你的数据,属于谁?活多久?要不要共享?

想清楚这三点,选型自然就出来了。

相关推荐
yuananyun2 小时前
APP 图标规范与设计全攻略:iOS/Android/Web 一次设计多端合规,快速出图
android·前端·ios
niech_cn3 小时前
uniapp开发App(iOS、Android、鸿蒙Next)之配置pages.json 页面路由(三)
android·ios·uni-app
游戏开发爱好者85 小时前
Linux 自动上传 App Store Connect:把 IPA 上传流程接进CI工作流
linux·运维·ios·ci/cd·小程序·uni-app·iphone
白玉cfc5 小时前
【iOS】底层原理:方法交换
macos·ios·cocoa
暗冰ཏོ6 小时前
2026 App 开发完整指南:Android、iOS、跨平台开发与安卓应用上线全流程
android·ios·uni-app·web app·app开发
人月神话-Lee1 天前
【图像处理】图像直方图——从“频率分布“到“智能决策“
图像处理·人工智能·ios·ai编程·swift
会Tk矩阵群控的小木1 天前
imessage虚拟机群发系统搭建:基于UTM+Frida的完整实现与海外社媒集成
macos·ios·objective-c·cocoa·开源软件·个人开发·tk矩阵
灰鲸广告联盟1 天前
新老用户广告价值不同?差异化策略如何实现收益最大化
android·开发语言·flutter·ios
划水的code搬运工小李1 天前
下载CSDN到PDF
开发语言·pdf·swift