Logo

site iconOneV | 王巍

开发者,专注于 iOS 和 Swift 方向。Kingfisher 作者。创办 ObjC 中国。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

OneV | 王巍 RSS 预览

编译器,靠你了!使用类型改善状态设计

2024-11-11 20:00:00

在程序的开发和运行过程中,人往往是最不可靠的环节:一个不小心,逻辑错误(也就是 bug!)可能会悄然保留下来并进入最终的产品。与此相对,编译器要可靠得多。如果程序中存在错误,编译器通常会直接阻止生成产品。Swift 拥有非常强大的类型系统,通过它,我们可以尝试将一些运行时的逻辑“封装”到类型系统中,从而在编译期提前发现潜在的问题和错误。这种依靠类型系统来“保存”逻辑的设计方式可以称为类型状态。 一个简单例子:端到端加密 定义和使用 这个例子源自实际工作的需求。假设我们需要设计一个客户端之间的消息系统,并支持端到端加密:也就是说,这些消息可能包含用户的隐私敏感内容。在用户设备上,这些消息可以以明文形式显示,但一旦需要离开用户设备、发送到服务端(并进一步传递到另一个目标客户端),则必须加密。如果错误地将未加密的信息发送出去,可能会带来安全隐患,甚至损害用户的信任。 一个“简洁”的设计思路是设计一个带有状态的 Message,它包含文本并用一个状态来表示是否已加密: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 struct Message { e...

逆流而上的设计 - Swift 所有权和 ~Copyable

2024-11-02 22:30:00

在 Rust 中,绝对安全和高效的内存使用得益于其独特的所有权(ownership)设计。七年前,Swift 团队发布了《所有权宣言》,以前瞻性的方式介绍了 Swift 中关于值的内存管理变化的一系列愿景。Swift 5.9 中(以和宣言里略微不同的语法)实现了这一愿景,引入了不可复制类型的标记 ~Copyable(non-copyable),以与 Rust 截然不同的(打补丁的)方式实现了更精确的所有权控制。在今年的 Swift 6 中,之前类型扩展(extension)和泛型(generic)不支持 ~Copyable 的不足也得到了解决,~Copyable 的可用性得到了提升。回顾 ~Copyable 及其设计,它为 Swift 引入了一种全新的设计思路:以往的协议是“为类型增加功能”,而 ~Copyable 则是“为类型解除限制”。本文尝试解释 ~Copyable 的设计和工作方式,以帮助读者更好地理解并利用这个特性。 ~Copyable 的工作方式 首先需要强调的是,即使目前完全不了解 Copyable 和 ~Copyable,以及相关的 consuming 和 b...

Swift 6 适配的一些体会以及对现状的小吐槽

2024-07-30 21:00:00

最近对手上的两三个项目进行了 Swift 6 的迁移,整体过程并不算顺利,颇有一种梦回 Swift 3 的感觉。不过,最终还是有所收获和心得。趁着记忆还新鲜,我想稍微总结一下。此外,针对目前社区里的一些声音,以及自己这些年的感受,我会在文章后半部分对 Swift 生态进行一些不太重要的小唠叨。 Swift 6 迁移 Swift 6 的最大“卖点”当然是并发编程和编译时就能保证的完全线程安全,这也是在进行 Swift 6 迁移时开发者工作量最大的来源。通过引入一系列语言工具 (主要是 actor 隔离和 Sendable 标注),Swift 6 在开启完全的严格并发检查 (也就是-strict-concurrency=complete) 时,理想状态下可以完全确保在编译阶段就将数据竞争 (data race) 和线程问题排除掉。 关于 Swift 并发编程,我之前写过一些关于并发初步以及结构化并发的文章。对于 actor、Sendable 的概念及其如何确保数据竞争不再发生,我在《Swift 异步和并发》中也有所介绍。近几年的 WWDC 上,Apple 通过若干 sessio...

SwiftLog 和 OSLog:选择、使用以及坑

2024-04-11 21:00:00

如果你还在用 NSLog 或者 print 打 log,那也许这篇文章正适合你,可以帮你转型到新的 log 方式。如果你已经在使用 OSLog 的相关功能,那也许本文可以帮助你加深理解,以及找到一些“进阶”用法。 选择:SwiftLog 和 OSLog 的区别 两者都是 Swift 中与 log 有关的框架。在进行选择时,我们的首要任务就是理清它们的区别。“SwiftLog 和 OSLog 我应该选哪个”,也是我在参加一个聚会时经常听到的问题。 SwiftLog 是前端 SwiftLog 首次发布于 2019 年,是一个 Swift server 主导的项目。它的目的是提供一个统一的日志记录接口,让包括服务器 app、命令行工具以及 iOS 和 macOS app 等各种使用 Swift 语言的场合下 (但主要是 server!),能使用同样的方法记录日志。SwiftLog 本身是一个 log 前端框架,这意味着它需要搭配后端使用:例如将日志输出到控制台、文件、数据库或远程日志收集服务。SwiftLog 注重模块化,允许开发者通过更换后端来灵活调整日志记录的行为。 OS...

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

2023-08-07 08:15:00

SwiftUI 遵循 Single Source of Truth 的原则,只有修改 View 所订阅的状态,才能改变 view tree 并触发对 body 的重新求值,进而刷新 UI。最初发布时,SwiftUI 提供了 @State、@ObservedObject 和 @EnvironmentObject 等属性包装器进行状态管理。在 iOS 14 中,Apple 添加了 @StateObject,它补全了 View 中持有引用类型实例的情况,使得 SwiftUI 的状态管理更加完善。 在订阅引用类型时,ObservableObject 扮演着 Model 类型的角色,但它存在一个严重的问题,即无法提供属性粒度的订阅。在 SwiftUI 的 View 中,对 ObservableObject 的订阅是基于整个实例的。只要 ObservableObject 上的任何一个 @Published 属性发生改变,都会触发整个实例的 objectWillChange 发布者发出变化,进而导致所有订阅了这个对象的 View 进行重新求值。在复杂的 SwiftUI 应用中,这可能会导致严...