dw+如何做自适应网站,手机在线制作图片,网站缩略图代码,网络营销品牌策略有哪些概览
在 Swift 5.9 中#xff0c;苹果为我们带来了全新的可观察框架 Observation#xff0c;它是观察者开发模式在 Swift 中的一个全新实现。 除了自身本领过硬以外#xff0c;Observation 框架和 SwiftUI 搭配起来也能相得益彰#xff0c;事倍功半。不过 Observable 对象…
概览
在 Swift 5.9 中苹果为我们带来了全新的可观察框架 Observation它是观察者开发模式在 Swift 中的一个全新实现。 除了自身本领过硬以外Observation 框架和 SwiftUI 搭配起来也能相得益彰事倍功半。不过 Observable 对象在 SwiftUI 中干起活来可得特别注意稍不留神结果就会出乎秃头码农们的意料之外。 在本篇博文中您将学到如下内容 概览1. 什么是 Observable 对象2. SwiftUI 中对于 Observable 对象承载的两种方式3. “原形毕露”4. 溯本回原总结 闲言少叙让我们马上开始 Observable 的探险之旅吧Let‘s go 1. 什么是 Observable 对象
Observable 对象不同于之前的 ObservedObject 对象是 Swift 5.9 新 Observation 框架中推出的一种原生可观察对象。 Observation 框架在 Swift 中提供了观察者设计模式的一个健壮、类型安全和高性能的实现。该模式允许可观察对象维护观察者列表并通知它们特定属性的改变。这样做的优点是可以实现对象的低耦合并允许在潜在多个观察者之间隐式分布更新。
创建 Observable 对象很简单我们只需用 Observable 宏修饰对应类的定义该类的实例即为 Observable 对象
Observable
class Foo {var name: Stringvar age: Intvar power: Doubleinit(name: String, age: Int, power: Double) {self.name nameself.age ageself.power power}
}// 创建 Observable 对象 foo
let foo Foo(name: hopy, age: 11, power: 5)2. SwiftUI 中对于 Observable 对象承载的两种方式
在 SwiftUI 中我们可以同样用 State 属性包装器来对 Observable 对象声明“真相之源”
Observable
class Model {var value: Intinit(_ value: Int) {self.value value}
}struct ContentView: View {State var model Model(11)var body: some View {NavigationStack {VStack {Text(value: \(model.value))Button(add 1) {model.value 1}}}}
}大家可以看到Observable 对象的行为和之前的 ObservableObject 对象如出一辙其内容的更改也会导致界面的刷新 不过与之前旧 ObservedObject 对象所不同的是Observable 对象在 SwiftUI 中无需显式用属性包裹器Property Wrapper修饰也能及时的根据变化刷新视图
struct ContentView: View { let model Model(11)var body: some View {NavigationStack {VStack {Text(value: \(model.value))Button(add 1) {model.value 1}}}}
}在上面的代码中我们的 model 对象没有任何修饰只是一个单纯的 let 属性。不过运行可以发现它的结果和之前一毛一样
这难道意味着在 SwiftUI 中用 State 或 let 来定义 Observable 对象没有任何区别么
非也非也
3. “原形毕露”
我们知道在 SwiftUI 中视图其实都是状态的函数。但状态不仅仅是视图的简单附庸它们又可以超然于视图之外。
简单来说当视图 body 被重新“求值”时非状态值会被重建但状态不会因为状态的生成周期被放在一个单独的存储区内和视图本身是分开的。
struct SubView: View {let model Model(0)var body: some View {RoundedRectangle(cornerRadius: 15.0).fill(.red).frame(width: 150, height: 150).overlay {VStack {Text(\(model.value))}}.onTapGesture {model.value 1}.foregroundStyle(.white)}
}struct SubStateView: View {State var model Model(0)var body: some View {RoundedRectangle(cornerRadius: 15.0).fill(.green).frame(width: 150, height: 150).foregroundStyle(.white).overlay {VStack {Text(\(model.value))}}.onTapGesture {model.value 1}.foregroundStyle(.white)}
}struct ContentView: View {State var id Int.random(in: 0...10000)var body: some View {NavigationStack {VStack {GroupBox(无状态 Observable 对象) {SubView()}GroupBox(State Observable 对象) {SubStateView()}Button(刷新\(id)) {id Int.random(in: 0...10000)}}.padding().font(.largeTitle.weight(.black)).navigationTitle(Observable 对象演示)}}
}对于上面的代码来说我们在主视图中创建了两个子视图SubView 和 SubStateView。其中 Observable 对象 model 在前者中不以状态承载而在后者中作为状态承载。 运行结果如上图所示当用户点击刷新按钮时会引起主视图中 Text 显示内容的改变从而导致主视图中两个子视图发生重建。可以看到以状态承载的 Observable 对象保持稳定而另一个 Observable 对象被重建了。
4. 溯本回原
从上面我们知道了问题的症结所以改善起来就很简单了我们只需要保持 Observable 对象本身的稳定性即可。
一种办法是在主视图中以状态承载该对象然后将其传递到子视图中去
struct SubView: View {let model: Modelvar body: some View {RoundedRectangle(cornerRadius: 15.0).fill(.red).frame(width: 150, height: 150).overlay {VStack {Text(\(model.value))}}.onTapGesture {model.value 1}.foregroundStyle(.white)}
}struct ContentView: View {State var model Model(0)State var id Int.random(in: 0...10000)var body: some View {NavigationStack {VStack {SubView(model: model)Button(刷新\(id)) {id Int.random(in: 0...10000)}}.padding().font(.largeTitle.weight(.black)).navigationTitle(Observable 对象演示).toolbar {Text(大熊猫侯佩 CSDN).font(.headline.weight(.bold)).foregroundStyle(.gray)}}}
}在上面的代码中如果可以保证主视图ContentView本身不被重建那么使用非状态来承载 model 对象也是可以的但不推荐
struct ContentView: View {let model Model(0)var body: some View {NavigationStack {VStack {// 由于主视图的强稳定性所以 SubView 对于 model 的引用也保持强稳定即使是非状态SubView(model: model)Button(刷新\(id)) {id Int.random(in: 0...10000)}}}}
}当然如果需要在子视图中也能更改 Observable 对象本身我们可以直接使用 Bindable 来修饰它们。
现在小伙伴们今后倘若在 SwiftUI 遇到类似的问题相信也可以迎刃而解啦棒棒哒 更多 Swift 5.9 中新 Observation 框架知识的介绍请小伙伴们移步如下链接观赏
Swift 5.9 与 SwiftUI 5.0 中新 Observation 框架应用之深入浅出 总结
在本篇博文中我们讨论了在 SwiftUI 中融合 Swift 5.9 新 Observable 对象的几种方式并比较了它们细微差别下的潜在陷阱最后提供了非常简单的解决之道。
感谢观赏再会