Swift @Observable属性包装器
Swift @Observable属性包装器

Swift @Observable属性包装器

在 Swift 中,@Observable 是 Swift 语言最近引入的一个属性包装器,用来简化状态管理和数据绑定。它的主要作用是让数据在发生变化时可以自动通知到观察它的视图,使界面自动更新。@Observable 主要与 SwiftUI 一起使用,可以让我们更轻松地管理视图状态。

主要特点

自动更新:标记为 @Observable 的类属性在发生变化时会通知到相关的 SwiftUI 视图,触发界面的自动刷新。

简洁:相比其他状态管理方式(如 @Published + @StateObject),@Observable 提供了一个更简洁的方案,减少了样板代码。

多属性观察:@Observable 允许在同一个类中管理多个属性的变化。

基本使用

要使用 @Observable,可以在 Swift 类中标记需要观察的属性:

import SwiftUI
import Observation

@Observable
class MyModel {
    var name: String = ""
    var age: Int = 0
}

然后在 SwiftUI 的视图中,可以直接使用这个 @Observable 标记的对象:

struct ContentView: View {
    @State private var model = MyModel()

    var body: some View {
        VStack {
            Text("Name: \(model.name)")
            Text("Age: \(model.age)")
            Button("Increase Age") {
                model.age += 1
            }
        }
    }
}

在这里,@Observable 使得 model 中的 name 和 age 的更改自动刷新 ContentView 的界面。

什么时候使用 @Observable

需要自动刷新 UI:当对象属性改变时,UI 需要自动响应更新。

简化代码:希望简化数据模型的属性定义,不用逐个加 @Published。

与 @Published 的区别

自动通知:@Observable 是一个较新的机制,它直接标记整个类,而 @Published 是一个属性包装器,必须逐个属性声明。

简洁性:@Observable 去除了手动声明 @StateObject 或 @ObservedObject 的需要,减少了额外的代码。

和@State使用

在 SwiftUI 中,@Observable 类型可以与 @State 一起使用,而不是 @StateObject,因为 @Observable 采用了 Swift 5.9 的新数据管理机制,并与 SwiftUI 更深层次地集成。这使得 SwiftUI 可以直接通过 @State 观察 @Observable 类型的对象。

具体原因

1、@Observable 的设计:

@Observable 是 Swift 5.9 引入的特性,提供了一种新的数据观察模型,不再依赖 ObservableObject 和 @Published。

@Observable 自动为类的属性提供了更新通知,而不需要实现 ObservableObject 协议。

2、@State 的支持:

@State 是专门为 SwiftUI 的视图状态设计的,SwiftUI 能够识别 @State 标记的 @Observable 对象并自动响应其更改。

因此,不需要额外使用 @StateObject 来创建一个外部对象的引用,@State 就可以支持 @Observable 对象的变化和管理生命周期。

3、为什么不是 @StateObject:

@StateObject 是用来管理符合 ObservableObject 协议的外部引用的生命周期,适合较重的对象(比如需要复杂的数据处理或依赖注入的模型对象)。

@Observable 对象已经具备了状态观察的功能,因此只需要 @State 来触发 SwiftUI 的自动更新。

示例

@Observable
class MyModel {
    var name: String = "Alice"
    var age: Int = 25
}

struct ContentView: View {
    @State private var model = MyModel()  // @State 直接用于管理 @Observable 对象

    var body: some View {
        VStack {
            Text("Name: \(model.name)")
            Text("Age: \(model.age)")
            Button("Increase Age") {
                model.age += 1
            }
        }
    }
}

使用 @State 是因为 @Observable 类型已经实现了观察和更新,而 @StateObject 主要用于管理 ObservableObject 类型对象的生命周期。

SwiftUI 可以直接观察 @Observable 对象中的属性变化,从而自动刷新视图。

ObservableObject和@Observable区别和关联

在使用 @Observable 的时候,不需要声明 ObservableObject。这是因为 @Observable 是 Swift 的新特性,它实现了与 ObservableObject 类似的功能,但更加简洁和自动化。

1、无需继承:

@Observable 直接作用于类,不需要继承 ObservableObject。这是因为它自动提供了观察者通知机制,无需额外实现 objectWillChange 或使用 @Published。

ObservableObject 是 SwiftUI 之前用来声明和管理可观察对象的协议。在使用 ObservableObject 时,我们通常需要用 @Published 标记每一个需要观察的属性,这样才能在属性发生变化时通知视图进行更新。

2、属性声明更简单:

使用 @Observable,只需将整个类声明为可观察对象,类中的每个属性都会自动通知视图更新。

使用 ObservableObject,则需要手动使用 @Published 来标记每一个可观察的属性。

3、Swift 语言层面的更新:

@Observable 是 Swift 新的 Observation 框架的一部分,是语言层面的更原生的特性,比 ObservableObject 的实现更加直接。

ObservableObject 是一个 SwiftUI 框架的协议,而 @Observable 则在语言层面更紧密地结合到 Swift 本身中。

4、替代关系:

@Observable 的引入使得某些情况下可以替代 ObservableObject,特别是在使用 SwiftUI 时,它可以减少很多样板代码。然而,ObservableObject 仍然存在并兼容于现有的 SwiftUI 代码,所以如果项目中已经使用了 ObservableObject,它不需要立即迁移。

代码对比

使用 ObservableObject 和 @Published 时:

import SwiftUI

class MyModel: ObservableObject {
    @Published var name: String = ""
    @Published var age: Int = 0
}

struct ContentView: View {
    @StateObject private var model = MyModel()

    var body: some View {
        VStack {
            Text("Name: \(model.name)")
            Text("Age: \(model.age)")
            Button("Increase Age") {
                model.age += 1
            }
        }
    }
}

使用 @Observable 时则更简单:

import SwiftUI
import Observation

@Observable
class MyModel {
    var name: String = ""
    var age: Int = 0
}

struct ContentView: View {
    @State private var model = MyModel()

    var body: some View {
        VStack {
            Text("Name: \(model.name)")
            Text("Age: \(model.age)")
            Button("Increase Age") {
                model.age += 1
            }
        }
    }
}

@Observable 是更简化的方案,直接为整个类提供观察支持,不再需要 ObservableObject 或 @Published。

它是 Swift 新的 Observation 框架的一部分,旨在简化代码和增强性能。

在新代码中,@Observable 可以优先使用,而 ObservableObject 仍然兼容现有代码。

总结

@Observable 提供了 Swift 和 SwiftUI 一体化的状态管理方式,更加简洁、自动化,适合用于简化界面与数据模型之间的同步工作。

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注