@state的一些琐事

先理解 Property Wrapper 是什么

@propertyWrapper 就是让你可以自定义 @ 修饰符 的机制。 @State@Binding 这些不是Swift内置的魔法,它们本质上就是普通的 struct,只不过被 @propertyWrapper 修饰了,所以才能用 @ 语法来用。 能理解吗?是不是还是很难理解,没事我写一个例子你就能理解了

swift 复制代码
假设你有一个属性,每次读取它都想打印一条日志:
var age: Int = 18
var age: Int = 18 { 
    didSet { print("age 变了,新值是 \(age)") }
}
但如果你有 100 个属性都需要这个功能呢?你要写 100 次 `didSet`?

Property Wrapper 就是用来解决这个问题的

你可以把"通用的包装逻辑"封装起来,然后像帖标签一样贴到任何属性上。

swift 复制代码
// 第一步:定义一个 Property Wrapper
@propertyWrapper
struct Logged {
    private var value: Int
    // initialValue 参数后面可以跟很多参数,自定义
    init(initialValue: Int) {
        self.value = initialValue
    }
    
    var wrappedValue: Int {
    //这里的get 和set 我们可以自定义任何我们想要的操作,比如有多个参数我们可以把这些参数拼接起来返回等等
        get { value }
        set {
            print("值变了,新值是 \(newValue)")  // 通用逻辑写在这里
            value = newValue
        }
    }
}

// 第二步:像贴标签一样使用它
@Logged var age = 18
@Logged var score = 100

// 现在 age 和 score 改变时,都会自动打印日志
age = 20   // 打印:值变了,新值是 20
score = 99 // 打印:值变了,新值是 99

所以 @propertyWrapper 本质上就是

把"对属性的操作逻辑"打包成一个 struct,然后用 @ 语法贴到属性上,让这个属性自动拥有那些逻辑。

回到 @State

@State 干的事情无非就是:

swift 复制代码
@propertyWrapper
public struct State<Value> {  
    // 1. 让你能直接赋初始值
    public init(initialValue value: Value)   
    // 2. 你平时用 brain 读写的就是这个 (这里set 之后苹果偷偷的去给你刷新了UI)
    public var wrappedValue: Value { get nonmutating set }    
    // 3. 你用 $brain 拿到的就是这个(一个 Binding)
    public var projectedValue: Binding<Value> { get }
}

@State 非常适合 struct 或者 enum 这样的值类型,它可以自动为我们完成从状态 到 UI 更新等一系列操作。但是它本身也有一些限制,我们在使用 @State 之前,对 于需要传递的状态,最好关心和审视下面这两个问题:

  1. 这个状态是属于单个 View 及其子层级,还是需要在平行的部件之间传递和使 用?@State 可以依靠 SwiftUI 框架完成 View 的自动订阅和刷新,但这是有 条件的:对于 @State 修饰的属性的访问,只能发生在 body 或者 body 所调 用的方法中。你不能在外部改变 @State 的值,它的所有相关操作和状态改变 都应该是和当前 View 挂钩的。如果你需要在多个 View 中共享数据,@State 可能不是很好的选择;如果还需要在 View 外部操作数据,那么 @State 甚至 就不是可选项了。
  2. 状态对应的数据结构是否足够简单?对于像是单个的 Bool 或者 String, @State 可以迅速对应。含有少数几个成员变量的值类型,也许使用 @State 也还不错。但是对于更复杂的情况,例如含有很多属性和方法的类型,可能其 中只有很少几个属性需要触发 UI 更新,也可能各个属性之间彼此有关联,那 么我们应该选择引用类型和更灵活的可自定义方式。
相关推荐
东坡肘子2 天前
我的 App 审核被卡了? -- 肘子的 Swift 周报 #128
人工智能·swiftui·swift
1024小神6 天前
记录xcode项目swiftui配置APP加载启动图
前端·ios·swiftui·swift
WaywardOne6 天前
SwiftUI中修饰符的顺序直接影响视图最终效果
ios·swiftui·ui kit
东坡肘子9 天前
50 岁的苹果和 51 岁的我 -- 肘子的 Swift 周报 #127
人工智能·swiftui·swift
东坡肘子16 天前
Macbook Neo:苹果重回校园的起点 -- 肘子的 Swift 周报 #126
人工智能·swiftui·swift
东坡肘子23 天前
OpenClaw 不错,但我好像没有那么需要 -- 肘子的 Swift 周报 #125
人工智能·swiftui·swift
东坡肘子1 个月前
春晚、机器人、AI 与 LLM -- 肘子的 Swift 周报 #124
人工智能·swiftui·swift
君赏1 个月前
第三十二章 接下来我们开始做`灭菌整板`页面
swiftui
君赏1 个月前
第三十章 接下来我们写首页的功能,首先是我们的`托盘绑定箱号`。
swiftui