这些属性包装器都在告诉 SwiftUI 以及。关键的划分是(、)与(、、),再加上谁负责该对象的生命周期。
@State@Binding@StateObject@ObservedObject@EnvironmentObject// Value state OWNED by this view
struct Toggle: View {
@State private var isOn = false // local source of truth
var body: some View {
Switch(isOn: $isOn) // $ makes a Binding
}
}
// A two-way reference to state owned ELSEWHERE
struct Switch: View {
@Binding var isOn: Bool // no ownership; reads+writes parent
var body: some View { Button("\(isOn)") { isOn.toggle() } }
}
final class CartModel: ObservableObject {
@Published var items: [Item] = [] // change => views re-render
}
struct CartScreen: View {
@StateObject private var model = CartModel() // OWNS: created once, survives re-renders
var body: some View { CartList(model: model) }
}
struct CartList: View {
@ObservedObject var model: CartModel // observes; owned by a parent
var body: some View { Text("\(model.items.count)") }
}
| 包装器 | 类型 | 所有权 | 使用场景 |
|---|---|---|---|
@State | 值 | 本视图 | 简单的本地状态 |
@Binding | 值 | 父视图 | 子视图编辑父视图的状态 |
@StateObject | 引用 | 本视图(创建一次) | 视图创建该 model |
@ObservedObject | 引用 | 别处 | model 从外部传入 |
@EnvironmentObject | 引用 | 祖先视图 | 在树的深处共享 |
@StateObject vs @ObservedObject 是经典陷阱。 用 @ObservedObject var m = Model() 创建一个 model,会在每次重新渲染时重新实例化它,从而静默地丢失状态。凡是视图创建该对象的地方都应使用 @StateObject。.environmentObject(...) 注入,@EnvironmentObject 会在运行时崩溃。选错包装器是 SwiftUI 状态 bug 的头号来源——闪烁的数值、滚动时被重置、或视图永远不更新。面试官问这个是因为 @StateObject vs @ObservedObject 的回答能立刻暴露你是否理解 SwiftUI 的所有权模型。
一个包含详细解答的 IT 面试题库——从初级到高级。
捐赠