前言

本期是 Swift 编辑组收拾周报的第四十二期,每个模块已开始成型。各位读者假如有好的提议,欢迎在文末留言。

Swift 周报在 GitHub 开源,欢迎提交 issue,投稿或引荐内容。现在方案每两周周一发布,欢迎志同道合的朋友一起参加周报收拾。

最火热的火焰,封锁在最缄默沉静的火山深处。最朴实纯真的智慧,就浅藏在Swift社区里!

周报精选

新闻和社区:苹果 CEO 库克透露接班方案,期望继任者来自公司内部

提案:Typed throws 提案正在审查

Swift 论坛:评论 MainActor 上的上下文切换和线程数

引荐博文:SwiftUI 中的效果域动画

论题评论:

那个活在回忆中的英俊少年,已渐渐变成了大叔模样。年月无情呀,那么各位程序猿和攻城狮们,你们心中最忧虑的容貌改变是哪一个呢?

上期论题成果

Swift 周报 第四十二期

这个成果反映了员工在工作和日子平衡方面的个体差异。一些人更注重通勤时间的运用效率,而另一些人则更注重在自己的房子中取得更大的舒适感和日子空间。这对公司供给灵敏的工作安排和住房福利或许有必定的启示。

新闻和社区

苹果 CEO 库克透露接班方案,期望继任者来自公司内部

11 月 21 日音讯,63 岁的苹果公司首席履行官蒂姆库克近日透露,苹果现已为他的继任者做好了 ” 非常详细 ” 的接班方案,但他也表示,他现在还没有离开苹果的方案。

Swift 周报 第四十二期

在 BBC Sounds 播客《Dua Lipa: At Your Service》的一次 45 分钟的采访中,库克向歌手 Dua Lipa 坦承,他不知道自己还会在苹果待多久。” 我爱这里,” 他说,回忆了自己在苹果的 25 年,” 我无法想象没有苹果的日子,所以我还会在这里一段时间。” 但是,当被问及苹果是否有任何 CEO 接班方案时,库克称:” 咱们是一家相信制定接班方案的公司,所以咱们有非常详细的接班方案。由于总会产生一些不行预测的工作。我明日或许会走错路旁边,期望不会产生这种事,我祈求不会。”

Dua Lipa 问道:” 你能说出谁是接班人吗?” 库克答复称,” 我不能说,但我想说的是,我的工作是找到几个有才能接班的人,我真的期望下一任首席履行官是来自苹果内部的人。所以这是我的人物:让董事会有几个人可以挑选。”

在这次采访中,库克讲述了自己作为苹果 CEO 的一天,共享了他在阿拉巴马州一个蓝领家庭长大的阅历,以及终究成为苹果 CEO。(文章来历:IT 之家)

音讯称苹果自研 5G 调制解调器开发再“难产”,将推迟到 2026 年

IT之家 11 月 17 日音讯,彭博社的马克・古尔曼(Mark Gurman)发布最新一期 Power On 时事通讯,表示苹果的自研 5G 调制解调器方案遇到麻烦。

IT之家注:苹果公司于 2019 年收买了英特尔大部分智能手机业务,并开始认真开发自己的调制解调器硬件,但开发过程并不顺利。

转存失利,主张直接上传图片文件

苹果公司原本方案 2024 年推出自研 5G 调制解调器芯片,并率先配备在 iPhone SE 机型上,但随后有音讯称拖延到 2025 年。

古尔曼在最新时事通讯中表示,苹果方案再次拖延推出自研 5G 调制解调器芯片时间,现在现已推迟到 2025 年年底或许 2026 年年头。

古尔曼在文章中透露,苹果的自研 5G 调制解调器芯片现在还处于前期阶段,或许落后竞争对手“数年”时间。

音讯称苹果现在自研的 5G 调制解调器芯片并不支撑 mmWave 技能,现在首要存在 2 个难题:第一是英特尔遗留代码,需求苹果重写,而增加新功用或许会中断现有功用;第二是开发芯片过程中,要小心绕过不侵略高通的专利。

一位苹果员工表示:“咱们接手了英特尔的一个失利项目,咱们盲目自信地认为可以成功”。据说苹果的硬件技能部门在很多项目中“捉襟见肘”,各项资源没有向其歪斜,导致难以处理过错。

提案

正在审查的提案

SE-0413 Typed throws 提案正在审查。

Swift 的过错处理模型答应符号为 throws 的函数和闭包指示它们可以经过引发过错来退出。过错值自身始终被类型擦除为 any Error。这种办法鼓舞以通用办法处理过错,而且对于大多数代码来说仍然是一个很好的默许选项。但是,有一些状况下类型擦除是不幸的,由于它不答应在或许且有必要处理一切过错的狭隘位置进行更准确的过错类型化,或许在类型擦除的本钱很高的状况下。

该提案引进了指定函数和闭包只能引发特定详细类型过错的才能。

Swift论坛

  1. 提议多句子 if/switch/do 表达式

内容归纳

该提案依据 SE-0380,引进了“then”要害字来处理 if 或 switch 表达式中的多个句子,从而促进更明晰的语法并进步可读性。 “then”要害字答应这些表达式每个分支有多个句子,从而简化了以前需求当即履行闭包或显式键入的场景。 此外,它还引进了“do”表达式,使代码结构愈加明晰,并处理 API 需求价值创立和后续骤变的状况。

该提案概述了详细规划,引进“then”作为上下文要害字,指定其在 if、switch 和 do 表达式中的用法。 它着重了解析歧义和或许的代替方案,探究比如在 Swift 中运用最终一个表达式或受 Rust 启示的分号停止等变体,同时评论它们对代码可读性和言语规划的影响。

总体而言,该提案旨在增强 Swift 的表达才能而不影响 ABI 安稳性,并邀请评论引进的“then”要害字的代替方案和潜在的解析复杂性。

介绍

该提案引进了 then 要害字,用于确认单个分支中包括多个句子的 if 或 switch 表达式的值。 它还介绍了 do 表达式。

动机

SE-0380 引进了运用 if 和 switch 句子作为表达式的功用。 正如该提案所述,这可以大大改善语法,例如在初始化变量时:

let width = switch scalar.value {
    case 0..<0x80: 1
    case 0x80..<0x0800: 2
    case 0x0800..<0x1_0000: 3
    default: 4
}

不然需求比如当即履行闭包或显式类型确认初始化之类的技能。 但是,该提案将让 switch 分支包括多个句子的才能作为未来的方向:

let width = switch scalar.value {
    case 0..<0x80: 1
    case 0x80..<0x0800: 2
    case 0x0800..<0x1_0000: 3
    default: 
      log("this is unexpected, investigate this")
      4  // error: Non-expression branch of 'switch' expression may only end with a 'throw'
}

当需求这样的分支时,当前用户有必要退回到旧技能。 该提案引进了一个新的上下文要害字,它答应 switch 保存为表达式:

let width = switch scalar.value {
    case 0..<0x80: 1
    case 0x80..<0x0800: 2
    case 0x0800..<0x1_0000: 3
    default: 
      log("this is unexpected, investigate this")
      then 4
}

then 可以类似地用于答应 if 表达式中的多句子分支。 该要害字的引进还使得独立的 do 表达式愈加可行。 它们有两个用例:

  1. 要从 do/catch 块的成功途径和失利途径生成值:
let foo: String = do {
    try bar()
} catch {
    "Error (error)"
}
  1. 当运用单个表达式无法轻松完结变量初始化时,可以初始化变量:
let icon: IconImage = do {
    let image = NSImage(
                    systemSymbolName: "something", 
                    accessibilityDescription: nil)!
    let preferredColor = NSColor(named: "AccentColor")!
    then IconImage(
            image, 
            isSymbol: true, 
            isBackgroundSupressed: true, 
            preferredColor: preferredColor.cgColor)
}

虽然上面的内容可以组成一个表达式,但声明单独的变量然后运用它们会更明晰。

在其他状况下,这是无法完结的,由于 API 的结构要求您首要创立一个值,然后更改其中的一部分:

let motionManager: CMMotionManager = {
    let manager = CMMotionManager()
    manager.deviceMotionUpdateInterval = 0.05
    return manager
}()

这种当即履行的闭包办法在 Swift 代码中很常见。 以至于在某些状况下,用户认为即使是单个表达式也有必要包括在闭包中。 do 表达式将供给更明晰的习惯用法来对这些进行分组。

  1. 评论借用和输入输出办法匹配的规划问题

内容归纳

评论环绕着经过启用借用和输入输出办法匹配来增强 Swift 的办法匹配、答应在不仿制或耗费值的状况下进行值匹配以及在办法匹配期间启用枚举的就地骤变来增强 Swift 的办法匹配。 首要规划问题包括:

  1. 新的绑定办法:引进“借用 x”和“inout x”分别作为借用和变异办法绑定的语法。 这些将答应借用或改动部分匹配值而不耗费它。
  2. 办法的一切权行为:剖析 Swift 中的各种办法类型以了解其一切权意义。 比如绑定、通配符、元组、枚举、可选打开、布尔值、动态转换和表达式办法之类的办法将依据其一切权行为进行评估。
  3. 确认办法匹配一切权:探究确认办法匹配的一切权行为的办法。 聚合办法(元组和枚举)遵从其组件之间最严格的一切权行为:借用、变异或消费。
  4. 确认开关的效果:评论怎么经过句法符号或从应用办法揣度一切权来确认开关对其主题的总体效果。 有人主张运用“&”符号来改动办法匹配。
  5. 条件中的一切权操控:考虑“if let”和“if case”构造中借用和 inout 办法绑定的意义。 这些新的绑定办法可用于可选打开,而且其行为类似于依据其一切权要求切换主题。

总体而言,咱们的方针是在 Swift 中引进更细致的办法匹配,答应在不耗费值的状况下进行借用和变异,并探究这些增强功用在各种言语结构(如 switch 句子和条件)中的意义。

  1. 评论怎么依靠 SwiftPM 作为一个库?

问题

理论上,SPM 是一个一般的 swift 包,您可以将其(运用东西链顺便的 SPM)构建为一般的 swift 包。但 swift-package-manager 存储库没有最新的 semver 标签,它运用“东西链”符号方案(swift-5.9.1-RELEASE)。 怎么依靠 SPM 作为library?

答复

到现在,libSwiftPM 尚未保护可以遵从语义版别操控的安稳 API。 您运用自己的 libSwiftPM 构建的软件包将从当前的 Swift 装置中提取 PackageDescription 模块,这或许与您运用的 libSwiftPM 版别不兼容。 这种不兼容性将表现为用于传递包清单和插件信息的不同序列化格式(自身是私有 API),这将导致含糊且难以诊断的过错。

作为以前保护过依据 libSwiftPM 构建的 CLI 东西,现在保护 SwiftPM 自身的人,我主张不要将其增加为依靠项。 它不适合在一起版别化并随 Swift 东西链分发的东西集之外运用。

假如您需求一个可以在包上操作的 CLI 界面,请改用 SwiftPM 指令插件,它们确实供给了安稳的 API。

  1. 评论MainActor 上的上下文切换和线程数

提问

我正在观看 Swift 并发:幕后我了解到,作为运用 Swift 并发的开发人员,咱们不应该违背不堵塞线程的运转时契约。 看来 Swift 的方针是运转与设备中 CPU 中心数量相同多的线程。 但是,会议结束时提出的一个观点引起了一些混乱。 演讲者提到,当咱们调用 MainActor 的办法时,会产生上下文切换,由于主线程与协作池中的线程是分隔的。 这引发了几个问题:

1、协作池中有多少个线程?

2、假如不包括主线程,这是否意味着实践的协作线程数是 numberOfCoresInDevice – 1?

3、为什么主线程不是协作池的一部分?

我的假设是,这或许是出于优化目的,答应主线程专心于 UI 任务; 不然,任何线程的任何继续都可以在挂起后在主线程上康复。

4、这里是否违背了运转时契约:当咱们将上下文切换到主线程时,咱们当前的线程应该被堵塞?

5、或许这个合约只针对咱们,开发者,体系可以随意违背吗?

无论怎么,看起来在这种状况下咱们有一个线程被堵塞。

或许,这个问题将作为前三个问题的答案得到答复,但无论怎么:为什么主线程不能像协作池中的线程相同工作? 只是接收有必要在主线程上履行的连续? 这将处理上下文切换问题。

答复

主线程首要经过 NSRunLoop 进行管理,由于它的存在时间比 Swift 存在的时间要长得多,更不用说 Swift 并发了。 当在默许办法下不行重入运转时,主调度行列由主运转循环供给服务。 在 Swift Concurrency 中,首要参加者的履行者担任将工作分派到该行列上,就像惯例参加者的履行者(默许履行者)将工作分派到协作行列上相同,如您链接的文章中所述

但并非一切进程都有主线程; 它首要是一个与 UI 相关的概念,像看护进程这样的非 UI 进程不需求它。

  1. 评论枚举事例要害途径:更新

内容概述

评论环绕运用 Swift 宏增强对枚举的要害途径支撑,特别是引进“事例要害途径”以更好地处理枚举事例。

  1. @CasePathable 宏:该宏为枚举事例生成实践的要害途径,称为“事例要害途径”。 这些要害途径供给动态事例查找功用,而且可以与惯例要害途径类似地运用。
  2. 运用示例:@CasePathable 宏答应完结各种功用:
  • 经过下标拜访枚举事例。
  • 运用 callAsFunction 嵌入新的有用负载。
  • 简化枚举事例检查和有用负载提取。
  • 运用 SwiftUI 绑定的大小写键途径,启用依据枚举大小写的导航和表单控件运用。
  • 运用大小写键途径组合应用程序功用,在构建和组合不同的应用程序功用时特别有用。
  1. 对库的影响:SwiftUINavigationComposable Architecture 等库已更新,以合并事例键途径,运用 Swift 键途径语法增强其功用、结构和可组合性。

供给的示例和事例研讨旨在展现事例要害途径的多功用性和实用性,着重它们在简化代码、增强 SwiftUI 绑定、组合应用程序功用等方面的潜力。 期望展现这些用例将鼓舞将事例要害途径归入言语中,并激发进一步的创新应用程序。

事例研讨:SwiftUI Bindings

大小写键途径使从枚举而不是一堆独立选项驱动 SwiftUI 导航成为或许。 例如,假如一个视图可以导航到两个不同的、互斥的功用,那么最好像这样建模:

struct FeatureView: View {
  @State var destination: Destination?
  enum Destination {
    case activity(ActivityModel)
    case settings(SettingsModel)
  }
  
}

但构建对 Destination 枚举的每种状况的绑定或许很困难,以便您可以运用 sheet(item:)popover(item:)(以及更多)视图修饰符。 但是假如你的枚举用 @CasePathable 注释

@CasePathable
enum Destination {
	// ...
}

然后咱们可以运用绑定上的“动态大小写查找”,答应它们经过点链语法转换为 SwiftUI 现有视图修饰符所期望的形状:

.sheet(item: self.$destination.activity) { model in
  ActivityView(model: model)
}
.popover(item: self.$destination.settings) { model in 
  SettingsView(model: model)
}

还可以运用 String 或 Bool 来驱动表单控件,例如 TextFields 和 Toggles,不然这些控件将被困在枚举事例中:

@CasePathable
enum Status {
  case inStock(quantity: Int)
  case outOfStock(isOnBackOrder: Bool)
}
@Binding var status: Status
switch self.item.status {
case .inStock:
  $status.inStock.map { $quantity in
    Section {
      Stepper("Quantity: (quantity)", value: $quantity)
      Button("Mark as sold out") {
        status = .outOfStock(isOnBackOrder: false)
      }
    } header: { Text("In stock") }
  }
case .outOfStock:
  $status.outOfStock.map { $isOnBackOrder in
    Section {
      Toggle("Is on back order?", isOn: $isOnBackOrder)
      Button("Is back in stock!") {
        status = .inStock(quantity: 1)
      }
    } header: { Text("Out of stock") }
  }
}

假如您想尝试其中任何一个,咱们的 SwiftUINavigation 库已更新,可以在运用 CaseKeyPath 进行绑定时界说动态成员查找。

事例研讨:Composing App Features

近 4 年前咱们开发事例途径的首要推动力是咱们的可组合架构库,它供给了一种界说功用并将它们组合在一起的结构化办法。 功用运用枚举来枚举应用程序中一切或许的用户操作,而且这些枚举嵌套在父/子域层中,而且需求事例途径来编写可以将这些功用抽象地粘合在一起的代码。

咱们还更新了该库以运用事例键途径,这答应人们经过运用简单且了解的键途径语法隔离子状况和操作来将功用组合在一起:

Reduce { state, action in
   // ...
 }
-.ifLet(.child, action: /Action.child) {
+.ifLet(.child, action: .child) {
   ChildFeature()
  }

这使咱们可以运用本机键途径给咱们带来的一切好处,例如 Xcode 自动完结和类型揣度。

引荐博文

依据 UI 交互目的理解的异常检测办法

摘要: 本文介绍了运用页面多模态信息在UI测试范畴的探究与实践经验。针对目的信息识别问题,咱们运用图画+文本+渲染布局特点信息探究出了一种交互目的簇识别模型,验证了依据自注意力的多模态方向可行性。

此模型可以识别出渲染树元素多维度的目的特点信息,同时运用聚类算法将节点聚成交互目的簇,可认为后续的任务供给结构化决策信息。在标注数据较少的状况下仍表现了较好的准确率以及泛化才能。后续方案经过扩大数据集、加强预练习等办法继续提高模型识别的精度。

SwiftUI 中的效果域动画

摘要: 文章介绍了在 SwiftUI 中运用效果域动画的新办法。首要,咱们回忆了以前在 SwiftUI 中处理动画的办法,并指出了其中的一些缺点。随后,咱们展现了怎么运用带有 value 参数的 animation 视图修饰符来限制动画规模,以及怎么处理多个可动画特点的状况。

接着,咱们介绍了 SwiftUI 中引进的 animation 视图修饰符的新变体,答应咱们运用 ViewBuilder 闭包来限制动画规模。最终,咱们还提到了在视图层次结构中保护效果域业务的办法。这些新办法为咱们在 SwiftUI 中创立准确且有限规模的动画供给了更灵敏的挑选。

线程调度和 Actors 的履行办法

摘要: 本文评论了在 Swift 中运用线程调度和 Actors 时的履行机制。Actors 可以确保代码在特定线程上履行,如主线程或后台线程,并协助同步拜访可变状况以避免数据竞争。

但是,开发人员常常误解 Actors 在非异步上下文中的线程调度,这是为了避免意外崩溃而至关重要的。作者主张在深入研讨调度的详细细节之前,先阅读他的两篇文章:《Actors in Swift: how to use and prevent data races》和《MainActor usage in Swift explained to dispatch to the main thread》,由于它们会向您介绍 Actors 的概念。在本文中,探讨了调用带有任何 actor 特点符号的办法的影响。

在异步上下文中,文章评论了运用 Actors 时的线程调度。通常状况下,您或许会在异步环境中运用 Actors 。假如您的调用代码拜访带有 actor 特点的办法,您有必要运用任务(task)或选用相同的大局 actor 。文章供给了相关的示例代码,并说明晰编译器怎么避免在非异步上下文中调度到 actor 线程。

论题评论

那个活在回忆中的英俊少年,已渐渐变成了大叔模样。年月无情呀,那么各位程序猿和攻城狮们,你们心中最忧虑的容貌改变是哪一个呢?

  1. 最忧虑越吃越肥壮,横向开展。
  2. 最忧虑逐步变厚的高度镜片。
  3. 最忧虑青丝若雪,青丝横生。
  4. 最忧虑秀发稀疏,日渐秃然。

欢迎在文末留言参加评论。

关于咱们

Swift社区是由 Swift 爱好者共同保护的公益组织,咱们在国内以微信公众号的运营为主,咱们会共享以 Swift实战SwiftUlSwift根底为中心的技能内容,也收拾收集优秀的学习资料。

特别感谢 Swift社区 编辑部的每一位编辑,感谢大家的辛苦付出,为 Swift社区 供给优质内容,为 Swift 言语的开展奉献自己的力气。