返回

State 仅在结构体中工作的潜在原因分析

IOS

概述

SwiftUI 的 State 属性包装器是一个强大的工具,用于在视图中存储和管理本地数据。然而,它有一个明显的限制:它只能在结构体中使用。这可能会让一些想要在类中使用 SwiftUI 的开发者感到沮丧。

SwiftUI 的内存管理机制

要理解为什么 @State 只能在结构体中使用,我们首先需要了解 SwiftUI 的内存管理机制。SwiftUI 使用一种称为“声明式编程范例”的编程方式。这意味着 SwiftUI 开发者只需声明他们想要构建的 UI,而无需指定如何构建它。SwiftUI 编译器会负责将声明转换为实际的 UI 代码。

这种声明式编程范例与命令式编程范例形成了鲜明的对比。在命令式编程中,开发者需要明确地指定如何构建 UI。这意味着开发者需要手动管理内存。

在 SwiftUI 中,内存管理由 SwiftUI 编译器负责。这意味着开发者不必担心手动管理内存。然而,这也意味着 SwiftUI 开发者对内存管理机制的控制更少。

视图更新机制

SwiftUI 还使用一种称为“视图更新机制”的机制来管理视图。视图更新机制负责在数据发生变化时更新视图。

视图更新机制的工作原理是,当数据发生变化时,SwiftUI 编译器会创建一个新的视图实例。然后,它会将新视图实例替换为旧视图实例。这种机制确保了视图始终是最新的。

然而,视图更新机制也意味着 SwiftUI 开发者无法在视图之间共享数据。这是因为当数据发生变化时,SwiftUI 编译器会创建一个新的视图实例。这意味着新视图实例没有旧视图实例的数据。

Swift 的类型系统和语义

Swift 的类型系统和语义也对 @State 只能在结构体中使用这一限制产生了影响。

在 Swift 中,结构体是一种值类型。这意味着当结构体发生变化时,它会创建一个新的结构体实例。相反,类是一种引用类型。这意味着当类发生变化时,它不会创建一个新的类实例。

SwiftUI 使用值类型来存储数据。这意味着当数据发生变化时,SwiftUI 编译器会创建一个新的数据实例。这与 SwiftUI 的视图更新机制相结合,意味着 SwiftUI 开发者无法在视图之间共享数据。

解决方案

虽然 @State 只能在结构体中使用,但这并不意味着开发者无法在类中使用 SwiftUI。有几种方法可以解决这个问题。

一种方法是使用 @ObservedObject 属性包装器。@ObservedObject 属性包装器允许开发者在类中观察其他对象的属性。这意味着当其他对象的属性发生变化时,类的属性也会发生变化。

另一种方法是使用 @StateObject 属性包装器。@StateObject 属性包装器允许开发者在类中存储自己的状态数据。这意味着类的属性可以不受其他对象的属性变化的影响。

结论

总而言之,State 只能在结构体中使用的原因是 SwiftUI 的内存管理机制、视图更新机制、以及 Swift 的类型系统和语义。有几种方法可以解决这个问题,包括使用 @ObservedObject 属性包装器和使用 @StateObject 属性包装器。