前语

本期是 Swift 修改组收拾周报的第三十八期,每个模块已初步成型。各位读者假如有好的提议,欢迎在文末留言。

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

三餐四季,春夏秋冬,普通如尔,与众不同。Swift社区陪你苦尽甘来,笑看山河星月!

周报精选

新闻和社区:苹果自研调制解调器芯片受挫:速度太慢简单过热,落后高通3年

提案:在导入声明上运用拜访等级修饰符

Swift 论坛:评论 Swift 测验的新办法

引荐博文:Swift 中运用 actors 完成线程安全

论题评论:

中秋遇上了国庆,诗和远方开端了烦躁,假日将至,你预备怎样过?

上期论题成果

Swift 周报 第三十八期

从投票成果能够看出,苹果的品牌忠诚度和名誉在一些用户中依然很高,而华为和小米等品牌则经过不同的性价比战略招引了其他一些用户。手机商场竞争激烈,顾客有幸具有多种选择,以满足他们的不同需求。

新闻和社区

苹果自研调制解调器芯片受挫:速度太慢简单过热,落后高通 3 年

上一年末的测验发现,苹果自研的调制解调器芯片速度太慢且简单过热,电路板尺度太大,占有半个 iPhone 的面积,无法运用。这些芯片基本上比高通最好的调制解调器芯片落后 3 年。

了解该项意图苹果前工程师和高管泄漏,因为技能应战、交流不畅,以及高层对测验规划芯片而不是购买芯片是否明智的问题存在不合,苹果调制解调器芯片的工程团队作业开展缓慢,且设定了不切实践的方针。

Swift 周报 第三十八期

苹果硬件技能高档副总裁约翰尼斯鲁吉(Johny Srouji)领导了芯片研制。

据苹果公司前工程师和高管泄漏,该公司原计划将其自研调制解调器芯片用在最新的 iPhone 机型中,但上一年年末的测验发现,该芯片速度太慢且简单过热,电路板尺度太大,占有半个 iPhone 的面积,无法运用。

调制解调器芯片的效果是衔接手机与无线运营商,iPhone 现在依靠高通公司出产的调制解调器芯片。本月上旬,高通宣告将苹果的收购合同延伸 3 年,业界估测苹果自主研制调制解调器芯片的计划遇到波折。

2018 年,苹果首席履行官蒂姆库克(Tim Cook)下达规划和制作调制解调器芯片的命令,并招聘数千名工程师。方针是切断苹果对高通的依靠。据估计,上一年苹果已向高通支付了超过 72 亿美元芯片收购费用。在 2017 年的诉讼中,苹果指控高通对其专利运用费收取过高费用。

了解该项意图苹果前工程师和高管告诉《华尔街日报》,因为技能应战、交流不畅,以及高层对测验规划芯片而不是购买芯片是否明智的问题存在不合,苹果调制解调器芯片的工程团队作业开展缓慢。团队被孤立在美国和国外的不同小组中,没有全球领导者。一些高管不鼓舞工程师传播有关延误或波折的坏消息,然后导致设定不切实践的方针和最后期限。

苹果在十多年前就致力于出产用于其产品的各种芯片。2010 年 1 月,苹果创始人史蒂夫乔布斯在第一代 iPad 发布会上低调展现了自研的 A4 芯片,这枚 45nm 制程的芯片由三星代工,一开端并不被业界看好。一年之后,苹果在 iPhone 4S 发布会上展现了第二代芯片 A5,性能提高巨大。尔后,苹果构建了由 A 系列(手机和平板)、M 系列(桌面电脑)、H 系列(耳机)、S 系列(手表)等多个产品线的芯片宗族。特别是在 2020 年,苹果用 M1 芯片代替 Mac 电脑中运用多年的英特尔处理器芯片,震动了商场。今年 9 月发布的 iPhone 15 Pro 系列更是搭载了全球首款 3nm 工艺制程芯片—— A17 Pro。

App Store 现已承受适用于最新版操作体系的 App 和游戏提交

iOS 17、iPadOS 17、macOS Sonoma、Apple tvOS 17 和 watchOS 10 行将面向全球用户推出。运用发布候选版 Xcode 15 和最新 SDK 构建你的 App 和游戏,经过 TestFlight 进行测验,然后提交到 App Store 以供审阅。现在,你能够着手从 Xcode Cloud 将你的 App 和游戏无缝布置到 TestFlight 和 App Store。凭借激动人心的新功用,以及针对各种言语、结构、东西和服务的重大改善,你能够在 Apple 渠道上供给愈加独特的体会。

Xcode 和 Swift:Xcode 15 供给增强的代码补齐功用、交互式预览和实时动画,可让你更快地推动 App 的编码和规划。Swift 经过引进宏解锁了多个新的 API 类型,不光表现力强,且直观易用。全新的 SwiftData 结构运用声明式代码,可轻松保存数据。SwiftUI 还支撑运用相位和关键帧创立更杂乱的动画,并经过新的 Observation 结构简化数据流。

小组件和实时活动:小组件现在支撑交互操作,而且能够在新的位置运转,例如 iPhone 上的待机界面、iPad 上的确定屏幕、Mac 上的桌面以及 Apple Watch 上的智能叠放。凭借 SwiftUI,体系会依据情境调整小组件的颜色和间距,然后提高它在各个渠道中的实用性。经过 WidgetKit 和 ActivityKit 构建的实时活动现已在 iPad 上推出,以协助用户实时了解 App 中正在产生的作业。

Metal:凭借新的游戏移植东西包,能够比以往更轻松地将游戏移植到 Mac,Metal 着色器转化器大大简化了游戏着色器和图形代码的转化进程。凭借最新的光线追寻更新,可将你的游戏和产品渲染器扩展到更逼真、更细腻的场景。此外还能运用许多其他增强功用,在 Apple 芯片上更轻松地供给精彩的游戏和专业 App。

App 便利指令:假如你适配了 App 便利指令,App 的首要功用会主动出现在聚集中,便运用户快速拜访 App 中最重要的视图和操作。新的规划让 App 便利指令的运转变得愈加简单,新的自然言语功用让用户能够愈加灵活地用自己的声音来履行你的便利指令。

App Store:凭借 StoreKit 中的全新 SwiftUI 视图,你现在能够更轻松地在一切渠道上推销 App 内购买项目和订阅。运用 Xcode 中的 StoreKit 测验、Apple 沙盒环境以及 TestFlight 的最新增强功用,你还能够对更多产品内容进行测验。经过按地区预购功用,你能够在新地区供给 App 并设置不同的发布日期,让用户更期待你的 App 发布。App Store 供给极为灵活且个性化的 App 发现体会,依据用户的爱好和偏好供给量身定制的引荐内容,协助他们找到更多超卓的 App。

提案

经过的提案

SE-0407 成员 Macro 一致性 提案经过检查。该提案已在 三十六期周报 正在检查的提案模块做了详细介绍。

正在检查的提案

SE-0409 在导入声明上运用拜访等级修饰符 提案正在检查。

经过在导入声明上运用拜访等级修饰符来声明依靠项的可见性,能够强制规则哪些声明能够引证导入的模块。能够将依靠项标记为仅对源文件、模块、包或一切客户端可见。这将让声明的拜访等级行为对依靠项和导入的声明也适用。此功用能够躲藏完成细节,有助于办理依靠项的分散。

驳回的提案

SE-0406 对 AsyncStream 的 Backpressure 支撑 提案被驳回。该提案已在 三十六期周报 正在检查的提案模块做了详细介绍。

Swift论坛

  1. 评论结构和类型(以前是匿名联合类型)

从状况检查中衍生出一个关于匿名联合类型主题的新评论线程:类型抛出。

关于这个主题的衍生评论是围绕这个评论开端的。

类型化抛出就像类一样,是静态类型信息的重要载体。 你所说的适当于说“不应答应类实例在弹性库中具有特定的类类型,而应始终为 AnyObject”。 这明显是十分过错的。 不小心将自己确定在特定过错类型中,然后在首要版本发布后懊悔的或许性不是言语问题,而是工程无能问题。 作者应该采取预防措施,在规划过错类型时考虑到未来的扩展(例如,具有可选元数据的结构而不是裸枚举)。

当咱们谈论这个论题时:

匿名联合类型 (A | B) 也是如此,它们只不过是某些通用枚举周围的语法糖(例如 Either<A, B>)。 这不是什么新鲜事,Swift 现已彻底能够表达这种类型,因而我不断听到的“因为编译器杂乱性而经常被回绝的提案”明显也是十分过错的。

定论:

类型体系有必要具有工程师认为适宜的表达能力,以使他们的代码具有表达能力。 仅仅因为有人想不出保存静态类型信息的理由(经过运用特定的过错类型或运用匿名联合类型),并不意味着没有理由。

  1. Swift运用推出 Swift SDK 生成器 咱们很快乐地宣告推出新的开源实用程序,它能够简化 Swift 包的穿插编译!

运用 Xcode 时,许多 Swift 开发人员每天都会运用从 macOS 到其他 Darwin 渠道的穿插编译。 与此同时,运用命令行开发东西对 Linux 和 Swift 支撑的其他渠道进行穿插编译并不那么简单设置。 经过 SE-0387 35,咱们期望缩小这一距离,并使穿插编译成为 SwiftPM 命令行界面中的一流功用。

尽管 SE-0387 指定了 Swift SDK 捆绑包的格局和文件体系布局,但它没有规则怎样生成这些捆绑包。 咱们供给了此类生成器的参阅完成,它支撑 macOS 作为主机渠道和一些首要的 Linux 发行版作为方针渠道。

区分 Swift SDK 作者和 Swift SDK 用户十分重要。 新的 Swift SDK Generator 应首要由 Swift SDK 作者运用,他们能够依据自己的需求对其进行自界说并发布自己的 Swift SDK 捆绑包。 反过来,Swift SDK 用户能够依靠 Swift 5.9 中引进的 swift Experimental-sdk 命令来装置 Swift SDK 作者之前生成的捆绑包。

咱们正在努力增加对 Swift 项目正式支撑的一切 Linux 发行版的支撑。

  1. 评论Swift 测验的新办法 我们好,

我很快乐地宣告一个新的开源项目,旨在探究 Swift 测验体会的改善。 我和我的同事最近几个月一直在致力于此作业,并取得了一些早期开展,咱们很快乐与我们共享。

受到 Swift 宏的启示,咱们构建了一个测验库 API,它能够:

运用名为 @Test 的附加宏供给有关各个测验的详细信息。 这使得许多新功用成为或许,例如表达需求、传递参数或增加自界说标签,一切这些都直接在代码中而不是单独的配置文件中完成。

运用拼写为 #expect(…) 的表达式宏,经过详细且可操作的故障信息验证测验中的预期条件。 它经过主动捕获传入表达式的值及其源代码来通知失利消息,而且比专门的断言函数更简单学习,因为它承受内置运算符表达式,如 #expect(a == b)

经过向函数增加参数并在 @Test 特点中指定其参数,能够运用不同的输入轻松重复测验屡次。

这是一个示例:它显现了一个测验函数,运用 @Test 表明,其间包含两个特征:自界说显现称号和决定测验是否应运转的条件。 该测验创立一辆食品卡车,在其间寄存食物,然后运用 #expect 检查食物数量是否等于咱们期望的值:

@Test("The Food Truck has enough burritos",
      .enabled(if: FoodTruck.isAvailable))
func foodAvailable() async throws {
    let foodTruck = FoodTruck()
    try await foodTruck.stock(.burrito, quanity: 15)
    #expect(foodTruck.quantity(of: .burrito) == 20)
}

假如上述测验失利,#expect 将捕获数量(of: .burrito) 等子表达式的值以及源代码文本。 这答应在输出中包含丰厚的诊断信息:

 Test "The Food Truck has enough burritos" recorded an issue at FoodTruckTests.swift:8:6:
Expectation failed: (foodTruck.quantity(of: .burrito)  15) == 20

运用这种办法,运用不同的输入屡次重复测验(称为参数化测验 15)也很简单。 @Test 特点能够包含参数,而且该函数将被重复调用并传递每个参数:

@Test(arguments: [Food.burrito, .taco, .iceCream])
func foodAvailable(food: Food) {
    let foodTruck = FoodTruck()
    #expect(foodTruck.quantity(of: food) == 0)
}

Swift 测验的新 API 方向深入探讨了咱们的愿景,描述了项意图方针,并展现了咱们提出的办法的更多示例。

这些主意已在名为 swift-testing 的新包中原型化,该包现在被认为是实验性的,没有引荐用于一般出产用处。 假如你感爱好,咱们鼓舞你克隆它,探究它的完成,并测验运用它为你的项目编写测验。

  1. 评论VSCode 5.9:停止服务器失利

自从升级到 5.9 以来,VSCode 上的 sourcekit-lsp 变得愈加不稳定,我不断收到“客户端 SourceKit 言语服务器:与服务器的衔接犯错。 封闭服务器。” 问题,它打印的唯一日志输出是:

[Error - 4:44:34 PM] Stopping server failed
  Message: Cannot call write after a stream was destroyed
  Code: -32099

我信任,这是应该解决该问题的 PR:Don’t crash when unregistering for change notifications of a file that isn’t watched by ahoppen Pull Request #828 apple/sourcekit-lsp GitHub

  1. 评论关于传递到异步效果域函数的闭包来说,Sendable 是否是必需的?

我一直在考虑以下函数代码。

public extension Database {
    func transaction<T>(_ closure: @Sendable @escaping (Database) async throws -> T) async throws -> T {
        try await self.transaction { db -> EventLoopFuture<T> in
            let promise = self.eventLoop.makePromise(of: T.self)
            promise.completeWithTask{ try await closure(db) }
            return promise.futureResult
        }.get()
    }
}

这是来自 Vapor 结构的实践代码。

以下是供参阅的网址:github.com/vapor/ Fluent-kit/blob/main/Sources/FluentKit/Concurrency/Database%2BConcurrency.swift 1

在这个业务函数中,参数闭包具有 @Sendable@escaping 特点。

我想知道是否能够将两者删去。

特别是,@Sendable 特点意味着传递给闭包的类型有必要是 Sendable,这施加了适当严厉的约束。因而,假如咱们能够省略它,那就便利多了。

我认为它能够被删去的原因是,尽管这个闭包的确被传递到工作循环线程,当它脱离交易功用时,它正在等候 EventLoopFuture.get(),确保闭包的函数调用完成。

换句话说,两个不同线程不或许同时调用闭包。

的确,理论上因为 eventLoop 类型被抽象为任何 EventLoop,完成一种将传递给 completeWithTask 的闭包存储到全局变量或类似的东西中的办法是或许的,但这关于 EventLoop 和 EventLoopFuture 来说明显是不自然的行为,我认为没有什么可担心的。

此外,我认为出于相同的原因能够消除@escaping。 闭包实践上并没有逃脱。

上面的主意或许是对的吗?

我很想听听有更多见地的人的主意来权衡。

作为参阅,详细完成如下:

public extension Database {
    func transaction<T>(_ closure: (any Database) async throws -> T) async throws -> T {
        try await withoutActuallyEscaping(closure) { (closure) in
            let closureBox = UncheckedSendableBox(closure)
            return try await self.transaction { db -> EventLoopFuture<T> in
                let dbBox = UncheckedSendableBox(db)
                let promise = self.eventLoop.makePromise(of: T.self)
                promise.completeWithTask {
                    let db = dbBox.value
                    let closure = closureBox.value
                    return try await closure(db)
                }
                return promise.futureResult
            }.get()
        }
    }
}

我信任这个主意能够推行。

我将这些承受值并答应运用闭包进行灵活处理的函数称为效果域函数。

这样的效果域函数的确能够是异步的,可是,即使它们是异步的,在我看来,只需效果域函数中的闭包履行是串行完成的,它们不一定有必要是 @Sendable@escaping

你对此有何观点?

答复

这个问题很好理解,但解决计划不是抛弃当前言语中的 Sendable 要求,而是让编译器能够推断出底子不需要它。 请参阅 Pitch 跨阻隔域安全发送非“可发送”值,了解编译器怎样增强此功用的示例。

我赞同你的观点,只需咱们扫除异步代码中不安全的行为,这种运用模式或许是安全的,但此刻我依然不愿意删去注释。

  1. 评论编写 TCP 客户端应用程序的引荐办法是什么?

我需要为 TCP/IP 上的自界说专有协议编写一个客户端。 我期望它能够在 macOS、iOS 和 Linux 上运用。 引荐的办法是什么?

我有一组现有的 Objective-C 代码来履行此操作,而且我只运用原始 BSD 套接字。 它们很简单,而且因为不需要是高性能服务器,所以我十分乐意阻塞:我只需将代码粘贴在 NSOperation 中,在串行 NSOperationQueue 上运转它,并运用回调来传递成果。 在 Swift 中运用 BSD 套接字感觉就像我在与该言语作斗争:许多都陷入了 UnsafePointer 领域。

我检查了 Mojave 和 Swift-NIO 中引进的网络结构,但在这两种情况下,我真的不确定怎样构建客户端。 我需要做许多来回操作:向事物发送命令,读回响应,发送下一个命令,读取响应等。经过单个通道读取处理程序(在 Swift-NIO 的情况下)感觉一切内容, 再次,就像我做错事一样。

有谁知道 Swift-NIO 类似的来回通讯示例吗? 或者我看错了方向?

答复

自从我上次检查我的代码以来现已过去很长时间了,我确信自那时起 API 现已产生了很大的变化,但对我协助最大的是检查 Java 的 Netty 文档。 Swift-NIO 现在好像有适当好的文档,所以我会先阅读一下。

相同,它现已很老了,而且作业或许现已产生了变化,但这里有一个简单的示例,说明 Swift-NIO 客户端和处理程序类怎样协同作业。 这个默许完成会让你遇到你提到的切当问题,可是假如你在 TCP 客户端类之外声明通道、处理程序、工作循环等,你能够处理处理程序类中产生的更改,例如断开衔接或接纳消息, 在客户端类的其他办法中。 我不确定这是否是“正确”的处理方式,但它足以让它在我正在构建的应用程序中顺畅运转。

你或许会考虑由 IBM 开发并在 macOS、iOS 和 Linux 上运转的 BlueSocket。

我向这个库增加了对 Windows 的支撑,并以 GreenSocket 的称号供给。

BlueSocket 此处(macOS、iOS、Linux): github.com/Kitura/Blue… github.com/litewrap/Gr…

  1. 评论协议扩展能够界说类 API 掩盖吗?

我有几个契合协议的 UIViewController 子类(它们不同享相同的父类)。 我想增加几个 UIViewController API 重写的默许完成,以防止在每个子类中重写它们。 无论怎样要让这项作业成功吗?

protocol StylingController {
}
extension StylingController where Self: UIViewController {
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        becomeFirstResponder()
    }
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        resignFirstResponder()
    }
}

答复

在这种情况下,只需创立两个父类而不是一个:一个根据 UIViewController,另一个根据 UITableViewController。 假如有许多重叠的功用,而且期望它尽或许DRY,能够进一步将通用功用提取到协议扩展中:

class BaseViewController: UIViewController, CommonVCFunctionality {
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        commonVCFunctionality()
    }
}
class BaseTableViewController: UITableViewController, CommonVCFunctionality {
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        commonVCFunctionality()
    }
}
protocol CommonVCFunctionality: AnyObject {
    func commonVCFunctionality()
}
extension CommonVCFunctionality {
    func commonVCFunctionality() { ... }
}

引荐博文

Swift 中运用 actors 完成线程安全

摘要: 本文介绍了在 Swift 中运用 actors 完成线程安全的办法。首要,文章回忆了 Store 类型的界说,它答应咱们可猜测地完成状况办理,但这个类型不是线程安全的。为了解决这个问题,文章运用了一个 NSRecursiveLock 类型的实例来确保线程安全。但是,作者指出运用锁存在一些缺点,并引进了 actors 这个新的 Swift 言语特性。介绍了怎样运用 actors 以及与运用锁比较的长处,并评论了 actor 的重入问题。最后总结了actors在 Swift 中的重要性和优势。

深入理解 Observation – 原理,back porting 和性能

摘要: 喵神这篇文章评论了 SwiftUI 中的状况办理,特别是引证类型的状况办理,以及 Apple 在 iOS 14 中推出的新 Observation 结构。Observation 结构能够在 View 中完成特点粒度的订阅,防止不必要的刷新。它实质上经过增加 @ObservationTracked 宏将存储特点转化为核算特点,并增加与 ObservationRegistrar 相关的内容来完成。经过阅读本文,你将更了解 SwiftUI 中的新 Observation 结构及其优势。

货拉拉 iOS 用户端 10 万分位 Crash 率攻坚之战

摘要: 该文首要介绍了货拉拉 iOS 用户端在 Crash 管理方面的经历和技能计划。文章探讨了 iOS 渠道下 Crash 监控计划的优缺点,并共享了自建 Crash 监控渠道的思路和经历。随后,总结了 Crash 管理的思路和经历,包含分级管理、版本追寻、定期分析和团队合作。最后,文章共享了常见的 Crash 类型及其解决计划,并总结了长期 Crash 管理的经历和收益。

论题评论

中秋遇上了国庆,诗和远方开端了烦躁,假日将至,你预备怎样过?

  1. 旅游团已报名,攻略计划已熟记,静待启程,我的青春我做主。
  2. 老婆孩子,三餐四季,和日子对线,已倾尽了一切,钱包已然羞涩,年月静好足矣。
  3. 钱不钱的无所谓,首要是我爬山嫌累,涉水呛口,梦想也是会变的嘛,西瓜啤酒,空调刷剧也是极好的。

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

关于咱们

Swift社区是由 Swift 爱好者一起维护的公益安排,咱们在国内以微信公众号的运营为主,咱们会共享以 Swift实战SwiftUlSwift根底为核心的技能内容,也收拾搜集优异的学习材料。

特别感谢 Swift社区 修改部的每一位修改,感谢我们的辛苦付出,为 Swift社区 供给优质内容,为 Swift 言语的开展贡献自己的力量。