当前位置: 首页 > news >正文

吉林企业做网站中国制造网网站类型

吉林企业做网站,中国制造网网站类型,大企业网站建设公司,装潢公司0. 概览 Swift 5.9 一声炮响为我们带来全新的宏(Macro)机制,也同时带来了干霄凌云的 Observation 框架。 Observation 框架可以增强通用场景下的使用,也可以搭配 SwiftUI 5.0 而获得双剑合璧的更强威力。 在本篇博文&#xff0c…

在这里插入图片描述

0. 概览

Swift 5.9 一声炮响为我们带来全新的宏(Macro)机制,也同时带来了干霄凌云的 Observation 框架。

在这里插入图片描述

Observation 框架可以增强通用场景下的使用,也可以搭配 SwiftUI 5.0 而获得双剑合璧的更强威力。

在本篇博文,您将学到如下内容:

  • 0. 概览
  • 1. @Observable 宏
  • 2. 通用情境下如何观察 Observable 对象?
  • 3. Observable 对象与 SwiftUI 珠联璧合
  • 4. 被“抛弃的” @EnvironmentObject
  • 5. 在视图中将不可变 Observable 对象转换为可变对象的妙招
  • 6. 总结

那么,就让我们赶快进入 Observation 奇妙的世界吧!

Let‘s go!!!😉


1. @Observable 宏

简单来说,Observation 框架为我们提供了集鲁棒性(robust)、安全性、高性能等三大特性为一身的 Swift 全新观察者设计模式。

它的核心功能在于:监视对象状态,并在改变时做出反应!

在这里插入图片描述

在 Swift 5.9 中,我们可以非常轻松的通过 @Observable 宏将普通类“转化为”可观察(Observable)类。自然,它们的实例都是可观察的:

@Observable
final class Hero {var name: Stringvar power: Intinit(name: String, power: Int) {self.name = nameself.power = power}
}@Observable
final class Model {var title: Stringvar createAt: Date?var heros: [Hero]init(title: String, heros: [Hero]) {self.title = titleself.createAt = Date.nowself.heros = heros}
}

如上代码所示,我们定义了两个可观察类 Model 和 Hero,就是这么简单!

2. 通用情境下如何观察 Observable 对象?

在一个对象成为可观察之后,我们可以通过 withObservationTracking() 方法随时监听它状态的改变:

在这里插入图片描述

我们可以将对象需要监听的属性放在 withObservationTracking() 的 apply 闭包中,当且仅当( Hero 中其它属性的改变不予理会)这些属性发生改变时其 onChange 闭包将会被调用:

let hero = Hero(name: "大熊猫侯佩", power: 5)func watching() {withObservationTracking({NSLog("力量参考值:\(hero.power)")}, onChange: {NSLog("改变之前的力量!:\(hero.power)")watching()})
}watching()hero.name = "地球熊猫"
hero.power = 11
hero.power = 121

以上代码输出如下:

在这里插入图片描述

使用 withObservationTracking() 方法有 3 点需要注意:

  1. 它默认只会被调用 1 次,所以上面为了能够重复监听,我们在 onChange 闭包里对 watching() 方法再次进行了调用;
  2. withObservationTracking() 方法的 apply 闭包不管如何都会被调用 1 次,即使其监听的属性从未改变过;
  3. 在监听闭包中只能得到属性改变前的旧值;

目前,上面测试代码在 Xcode 15 的 Playground 中编译会报错,提示如下:

error: test15.playground:8:13: error: external macro implementation type ‘ObservationMacros.ObservableMacro’ could not be found for macro ‘Observable()’
final class Hero {
^

Observation.Observable:2:180: note: ‘Observable()’ declared here
@attached(member, names: named(_$observationRegistrar), named(access), named(withMutation)) @attached(memberAttribute) @attached(extension, conformances: Observable) public macro Observable() = #externalMacro(module: “ObservationMacros”, type: “ObservableMacro”)

小伙伴们可以把它们放在 Xcode 的 Command Line Tool 项目中进行测试:

在这里插入图片描述


3. Observable 对象与 SwiftUI 珠联璧合

要想发挥 Observable 对象的最大威力,我们需要 SwiftUI 来一拍即合。

在 SwiftUI 中,我们无需再显式调用 withObservationTracking() 方法来监听改变,如虎添翼的 SwiftUI 已为我们自动完成了所有这一切!

struct ContentView: View {let model = Model(title: "地球超级英雄", heros: [])var body: some View {        NavigationStack {Form {LabeledContent(content: {Text(model.title)}, label: {Text("藏匿点名称")})LabeledContent(content: {Text(model.createAt?.formatted(date: .omitted, time: .standard) ?? "无")}, label: {Text("更新时间")})Button("刷新") {// SwiftUI 会自动监听可观察对象的改变,并刷新界面model.title = "爱丽丝仙境兔子洞"model.createAt = Date.now}}.navigationTitle(model.title)}}
}

注意,上面代码中 model 属性只是一个普通的 let 常量,即便如此 model 的改变仍会反映到界面上:

在这里插入图片描述

4. 被“抛弃的” @EnvironmentObject

有了 Swift 5.9 中新 Observation 框架加入游戏,在 SwiftUI 5.0 中 EnvironmentObject 再无用武之地,我们仅用 Environment 即可搞定一切!

早在 SwiftUI 1.0 版本时,其就已经提供了 Environment 对应的构造器:

@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
@frozen @propertyWrapper public struct Environment<Value> : DynamicProperty {...}

有了新 Observation 框架的入驻,结合其 Observable 可观察对象,Environment 可以再次大放异彩:

struct HeroListView: View {@Environment(Model.self) var modelvar body: some View {List(model.heros) { hero inHStack {Text(hero.name).font(.headline)Spacer()Text("\(hero.power)").font(.subheadline).foregroundStyle(.gray)}}}
}struct ContentView: View {@State var model = Model(title: "地球超级英雄", heros: [.init(name: "大熊猫侯佩", power: 5),.init(name: "孙悟空", power: 1000),.init(name: "哪吒", power: 511)])var body: some View {        NavigationStack {Form {NavigationLink(destination: HeroListView().environment(model)) {Text("查看所有英雄")}}.navigationTitle(model.title)}}
}

现在,即使跨越多重层级关系我们也可以只通过 @Environment 而不用 @EnvironmentObject 来完成状态的间接传递了,是不是很赞呢?👍🏻

5. 在视图中将不可变 Observable 对象转换为可变对象的妙招

介绍了以上这许多,就还剩一个主题没有涉及:**Observable 对象的可变性!
**

为了能够在子视图中更改对应的可观察对象,我们可以用 @Bindable 修饰传入的 Observable 对象:

struct HeroView: View {@Bindable var hero: Herovar body: some View {Form {TextField("名称", text: $hero.name)TextField("力量", text: .init(get: {String(hero.power) }, set: {hero.power = Int($0) ?? 0}))}}
}

不过,对于之前 @Environment 那个例子来说,如何达到子视图能够修改传入的 @Environment 可观察对象呢?

别急,我们可以利用称为“临时可变(Temporary Variable)”的技术将原先不可变的可观察对象改为可变:

extension Hero: Identifiable {var id: String {name}
}struct HeroListView: View {@Environment(Model.self) var modelvar body: some View {// 在 body 内将 model 改为可变@Bindable var model = modelVStack {List(model.heros) { hero inHStack {Text(hero.name).font(.headline)Spacer()Text("\(hero.power)").font(.subheadline).foregroundStyle(.gray)}}.safeAreaInset(edge: .bottom) {// 绑定可变 model 中的状态以修改英雄名称TextField("", text: $model.heros[0].name).padding()} }}
}

运行效果如下:

在这里插入图片描述

“临时可变”这一技术可以用于视图中任何化“不变”为“可变”的场景中,当然对于直接视图间对象的传递,我们可以使用 @Bindable 这一更为“正统”的方法。

6. 总结

在本篇博文中,我们讨论了在 Swift 5.0 和 SwiftUI 5.0 中大放异彩 Observation 框架的使用,并就诸多技术细节问题给与了详细的介绍,愿君喜欢。

感谢观赏,再会!😎

http://www.hengruixuexiao.com/news/7567.html

相关文章:

  • 网站上线模板在线咨询 1 网站宣传
  • 网站开发者什么浏览器网易疫情实时最新数据
  • 新中式家具靠谱的seo收费
  • 内部网站链接怎么做如何快速推广网上国网
  • 网站排名应该怎么做app怎么推广
  • 请人做网站要百度关键词价格查询
  • 电脑网站历史记录怎么查看百度推广手机版
  • 建设银行 网站用户变成个人用户最新资讯热点
  • 网站设计与网页制作培训百度网盘电脑版登录入口
  • 郑州专门做网站南昌网站seo
  • 中国室内设计公司杭州seo代理公司
  • 自己做网站能关联支付宝吗关键词挖掘排名
  • 哪些网站可以做花店推广网站优化是什么
  • 做网站用买服务器码百度推广的广告真实可信吗
  • 做空比特币的网站seo对网络推广的作用是
  • app开发网站排行榜找客户资源的软件哪个最靠谱
  • 广州贸易网站上海优化公司选哪个
  • 郑州网站优化哪家好青岛爱城市网app官方网站
  • 做阿里巴巴网站图片尺寸上海网站建设公司排名
  • 长沙娱乐网站开发长春网站优化团队
  • 仿中国化妆品网站模板深圳网站开发技术
  • 让你有做黑客感觉的网站营销方案
  • 做兼职哪个网站可靠网站收录什么意思
  • Pcb通过网站做外贸seo网络排名优化方法
  • 自己做的网站被攻击了灰色词快速排名接单
  • 申请域名之后如何做网站seo排名怎么样
  • js获取网站域名推广计划方案模板
  • 东莞建网站公司哪个好一键优化免费下载
  • 海报制作网站免费营销策划咨询机构
  • 360百度网站怎么做店面怎么做位置定位