SwiftUI 七年后:平庸的故事

在 2019 年发布七年后,SwiftUI 的初衷是成为 Apple 平台跨平台 UI 开发的成熟、生产级未来。然而,许多资深工程师现在将其视为一个处于永久 Beta 状态的框架,以精确的工程化换取了便利性的幻觉。

不可预测的数据流与响应式

SwiftUI 的数据流被描述为“黑盒”,实现可预测的行为几乎是不可能的。虽然“单一事实来源”的概念在理论上很有吸引力,但其实际实现已演变成一系列令人困惑的属性包装器(property wrappers)和宏(macros)。

  • 状态管理的演进: 该框架始于 @State@BindingObservedObject。由于性能问题和过度重新渲染,Apple 引入了 Observation 框架和 @Observable 宏。
  • 缺乏透明度: 开发者报告称,即使使用像 Self._printChanges() 这样未公开的调试 API,也往往无法确切知道视图会更新多少次,或者为什么会触发特定的更新。

布局引擎的脆弱性与 GeometryReader 陷阱

SwiftUI 基于尺寸协商(size negotiation)的布局系统通常被描述为不可预测且脆弱,尤其是在构建复杂的界面(如自定义侧边栏或悬浮视图)时。

  • 布局不一致性: 即使是 Apple 官方的教程,在最新的 macOS 版本上运行时也会出现布局损坏的情况。
  • GeometryReader 的权宜之计: 当声明式系统失效时,开发者往往不得不求助于 GeometryReader 来手动计算坐标。这被视为一种“败北的承认”,因为它消除了声明式的优势,并增加了比传统的 Auto Layout 系统更高的冗余度。

API 不稳定性与功能对等性差距

与 UIKit 和 AppKit 等传统框架相比,SwiftUI 在功能对等性方面持续挣扎。这导致代码库中充满了为了维持向后兼容性而添加的 if #available 检查。

  • 功能实现延迟: 尽管基础功能在传统框架中已存在数十年,但诸如在滚动时收起键盘(iOS 16)或通过 AsyncImage 显示网络图片(iOS 15)等功能,在 SwiftUI 中花费了数年才实现。
  • 组件替换: Apple 有时并不修复有 Bug 的组件,而是直接将其整体替换(例如,用 NavigationStack 替换 NavigationView),迫使开发者必须为不同的 OS 版本维护单独的代码分支。
  • 缓存限制: 截至 2026 年 7 月,某些用于图像缓存的关键 API 仍处于 Beta 阶段,迫使开发者必须构建自定义的获取器和缓存层。

性能差异

对比测试表明,SwiftUI 的性能往往落后于 UIKit,尤其是在处理数据密集型视图时。

  • 滚动性能: 即使在高端硬件上,SwiftUI 中简单的图像库和大型网格也往往感觉不如 UIKit 的对应实现流畅。
  • 优化开销: 获得可接受的性能通常需要掌握晦涩的优化技巧,这与该框架承诺的简洁性相悖。

“一次学习,随处应用”的迷思

虽然 Apple 将 SwiftUI 营销为一种“只需学习一次这些工具,然后就可以随处应用”的方式,但现实是,为 6 英寸的手机设计的 UI 与为 27 英寸的桌面设计的 UI 有着本质的区别。

  • 平台差异: 在 iOS 上学到的概念很少能直接应用于 macOS 布局,否则就会导致“异类”的 UI,感觉像是移植的 iPad 应用。
  • 实现不一致性: 同一视图在不同的 Apple 平台上的实现往往不一致,导致了沉重的调试工作流:“学习一次,学习两次,应用在某处,调试到处都是。”

向“足够好”的哲学转变

人们越来越担心,SwiftUI 代表了 Apple 从不妥协的匠心精神向“速度”和“足够好”的产品文化转变。

  • Bug 的常态化: 这种转变可以通过官方应用中的持续性 Bug 来证明(例如,Apple Music 队列跳转、主屏幕图标重复、以及 Logic Pro 中缺失的本地化)。

  • 与传统时代的对比: 这与最初的 Cocoa 和 Aqua 时代形成鲜明对比,在那个时代,此类视觉故障和不稳定性被认为是不可接受的的。

社区观点与反论点

开发者讨论揭示了那些将 SwiftUI 视为失败者与那些将其视为强大(尽管不完美)工具者之间的分歧。

"SwiftUI 是那种让简单的事情变得更容易完成,但让困难的事情变得更难的框架。它是一个新手陷阱。"

"我一直在使用 SwiftUI 而没有遇到重大性能问题……我根据需要进行性能分析并修复。我早期工作的一家工作室用 UIKit 编写了我们所有的游戏原型……当性能下降时,我们会切换到合适的工具。"

"对于 90% 的工作,SwiftUI 是好的,但对于剩下的 10% 你需要 AppKit。对于我的应用……我需要在列表中加载并显示大量的聊天项,SwiftUI 在这方面表现得很差。"

一些开发者认为,挫折感源于“UIKit 守旧派”的心态,并且对于简单的应用,SwiftUI 比那些冗余繁琐的传统框架更具生产力。

Sources