对标Flutter 7年,开发者发文炮轰苹果SwiftUI:它至今仍像一个“长期测试版”

CSDN·2026年08月04日 18:08
开发者Yakov Manshin评SwiftUI七年仍平庸问题多

7年前,苹果在 2019 年 WWDC 的压轴环节,正式向外界公布了全新的 UI 框架 SwiftUI。

这是一个姗姗来迟的产品——相比 Google 的 Flutter,SwiftUI 足足晚了两年亮相。但苹果依然选择将它放在当年 WWDC 的最后重磅发布,足以看出这套新框架在苹果内部的重要地位。

对于开发者而言,SwiftUI 为 iOS、macOS、watchOS、tvOS 等设备提供了一套统一的 UI 框架,它曾经承载着一个非常美好的愿景:未来,开发 Apple 生态应用将不再需要面对不同平台间割裂的开发体验。当时,无数人翘首以盼,期待这会成为苹果下一代应用开发的基石。

但 7 年过去,曾经的期待,如今还剩下多少?

来自一位开发者 Yakov Manshin 的评价或许代表了不少开发者的真实感受:“到了 2026 年,SwiftUI 依然给许多开发者一种‘长期测试版’的感觉。

这句话迅速引发了开发者社区的共鸣。

在他发表的《SwiftUI After 7 Years: A Story of Mediocrity》一文中,Yakov Manshin 回顾了 SwiftUI 七年来的发展历程,并试图回答一个问题:为什么一个曾经让开发者充满期待的框架,最终却逐渐成为许多资深工程师眼中的失望之作?

接下来,他将拆解苹果的 SwiftUI 在性能、布局可预测性等方面长期存在的问题,梳理其数据流设计不断变化带来的混乱,以及令人头疼的向后兼容问题——这些问题迫使开发者不得不依赖大量适配层和临时方案,才能让项目继续稳定运行。

通过真实案例,包括苹果官方 SwiftUI 教程自身暴露的问题,以及 SwiftUI 与 UIKit 的性能正面对比,下文也试图展示:SwiftUI 看似带来了更简单、更现代的开发体验,但这种简化背后,也意味着开发者逐渐失去了对应用行为的精准控制。

而这篇文章讨论的,其实并不只是一个 UI 框架的问题。在更深层次上,它也折射出苹果软件开发文化的变化——从早期 Cocoa、Aqua 和 Auto Layout 时代对产品工艺、细节打磨近乎苛刻的追求,到如今更加倾向于“够用就行”的现代企业文化。

如果你已经厌倦了不断为 SwiftUI 的缺陷寻找解释,反复与布局 Bug 斗争,或者一次次替苹果完成本该由他们承担的质量验证工作,那么这篇文章或许值得一读。

来源:https://ykvm.com/2026/07/swiftui-a-story-of-mediocrity/

SwiftUI 于 2019 年正式发布,并引发了巨大的关注。我当时就在现场,也亲眼见证了这一切。苹果当时承诺,它将终结开发者与 Auto Layout 长期斗争的时代,也不必因为一次微小的改动就反复重构整个应用。

取而代之的,是声明式语法、单一数据源、内置动画、即时预览,以及代码在苹果全平台之间的复用能力。对我来说,这听起来好得令人难以置信。

事实证明,确实如此。

到了现在,最初的兴奋感不仅已经消退,甚至逐渐转变成一种越来越强烈的职业挫败感。

而七年之后,“SwiftUI 仍然只是一个年轻框架”这种说法,已经站不住脚了。在这个行业里,七年几乎等同于一个漫长时代。它大致相当于从这个版本到那个版本之间的时间跨度,也超过了第一代 iPhone 发布到 iOS 7 重新设计之间的时间。

相比之下,SwiftUI 给人的感觉更像是一直处于测试阶段。每一个新功能背后,都伴随着一堆隐藏在细则里的限制条件。每一次布局修复,都可能导致两个你根本没有修改过的地方出现新的问题。

说实话,我已经厌倦了在自己的项目里不断为这些问题寻找借口。

为什么 SwiftUI 会出现

不过,在我们深入了解 SwiftUI 的具体优势和缺陷之前,我们先来看看 SwiftUI 为什么会出现。

这并不完全是因为苹果想要为开发者提供更好的开发工具,而是因为它某种程度上不得不这么做。苹果需要回应来自竞争对手的压力。

到了 2010 年代中期,Facebook 的 React 已经成为 Web 开发领域事实上的标准,随后 React Native 和谷歌的 Flutter 也开始向移动平台发起进攻。这两个框架都采用了响应式和声明式的设计理念。

从任何一家企业的角度来看,继续开发原生应用开始显得越来越不划算。相比之下,他们可以使用同一套代码库同时支持 iOS 和 Android,并且还能复用自己网站上的组件。

我认为还有另一个原因,那就是 Mac App Store。

你可以回忆一下,上一次打开它是什么时候?你上一次在 Mac 上安装一个新的原生应用又是什么时候?没错,我也是一样。

iOS App Store 是苹果向服务业务转型过程中的关键一步,原因在于它可以从每一笔交易中抽取 30% 的分成。但在 Mac 平台上,许多应用要么只能通过浏览器使用,要么只是基于 Electron 封装的 Web 应用。

SwiftUI 原本被寄予厚望,希望同时解决这两个问题:一方面,让开发者继续留在原生生态中构建新的应用;另一方面,让已有应用更容易迁移到 Mac 平台。

响应式数据流、声明式布局,以及跨平台支持,是 SwiftUI 最核心的卖点。

那么,苹果是否兑现了这些承诺?让我们继续深入看看。

数据流

一直困扰着资深工程师(包括我自己)的一大痛点,就是数据流问题。理论上,“单一数据源”听起来像是一个完美的设计理念。但在实际使用中,它却变成了一团由属性包装器、宏以及不断变化的配套框架组成的混乱系统。

最开始,我们使用的是 @State、@Binding 和 ObservedObject。随后苹果意识到这种方式的性能表现非常糟糕,SwiftUI 会不断重新渲染视图。

于是,它推出了 Observation 框架以及 @Observable 宏。苹果试图通过编译器层面的技巧来解决这个问题,但显然这还远远不够,因此布局引擎依旧像是在不断猜测。

在 SwiftUI 中,你永远无法确定一个视图到底会更新多少次,以及它为什么会选择在某个时刻进行更新。即使使用那些没有公开文档的调试 API,也无法获得完整的信息。

SwiftUI 的数据流确实是响应式的——但有时候,我甚至希望它不要这么响应,因为它经常以错误的方式做出反应。它会响应那些本应该忽略的变化,却忽略那些真正重要的变化。

在我看来,SwiftUI 的响应机制就像一个黑盒:它让实现可预测的行为变得几乎不可能。

布局系统

这也引出了 SwiftUI 在架构层面的问题。接下来,我们聊聊 SwiftUI 的布局系统。

如果你曾经构建过任何复杂一点的界面,那么你一定知道 SwiftUI 带来的挫败感。它的布局引擎极其不可预测。

SwiftUI 建立在“尺寸协商”的理念之上。在发布会演示中,这听起来非常合理,但当你真正尝试构建一个浮动视图或者自定义侧边栏时,它就会变成一场噩梦。

说到自定义侧边栏,苹果 SwiftUI 教程里的那个示例项目(https://developer.apple.com/tutorials/swiftui/creating-a-macos-app)使用的是一个非常标准、没有任何定制的侧边栏。你用最新版 Xcode 构建项目,再用最新版 macOS 启动应用——结果却会看到这样的情况。

我第一次注意到这个问题是在两年多以前,而从那以后,一切都没有改变。

哦,抱歉,有一件事变了。

由于 Liquid Glass 的加入,现在按钮的尺寸也发生了变化——当然,这个问题严格来说并不能算是 SwiftUI 的问题。

但真正属于 SwiftUI 的问题,是整个 UI 布局系统的脆弱性。它们会以最意想不到的方式、在最不合适的时刻崩溃。

你可以在真正投入生产的应用中看到这种情况,比如 UTM。它是一款非常出色的工程作品,但由于大量依赖 SwiftUI,有时候它给人的感觉更像是一个早期原型。

最终,你会发现自己不得不用 GeometryReader 包裹所有东西。而这其实就是一种彻底失败的表现。一旦使用了 GeometryReader,你就已经失去了 SwiftUI 最核心的声明式优势。现在,你必须手动计算坐标,而且代码量甚至比 Auto Layout 还要复杂——这本身就非常讽刺。

更糟糕的是,仅仅因为 SwiftUI 的布局系统又发生了一次变化,你可能下一次更新时就不得不重新编写所有坐标计算逻辑。

API 稳定性与功能完整性

接下来,我们聊聊 API 稳定性以及功能完整性——或者说,SwiftUI 在这方面的欠缺。

如果你查看任何一个现代 SwiftUI 项目的代码库,你都会发现里面充斥着大量 if #available 判断,多到几乎令人觉得滑稽——实际上却令人尴尬。

2019 年的时候,有人还在畅谈“写更少的代码,写更好的代码”。那么七年过去之后,我们得到的是什么?

比如说,你希望像从 iOS 7 时代开始那样,在用户滚动页面时隐藏键盘。抱歉,在 SwiftUI 中实现这个功能,你需要 iOS 16。

也许你也想让用户自定义窗口工具栏,就像他们从 2001 年(大概是那个时候)开始就可以做到的事情一样。而 SwiftUI 直到几年前才终于获得了这个所谓的“突破性”功能。

然后还有一个最基础的任务:显示你从网络获取的图片。

不过,你最好自己写一个图片加载器,因为 AsyncImage 直到 iOS 15 才被引入。

但如果你还希望对这些图片进行缓存,我有一个坏消息告诉你:你根本做不到。因为直到现在(2026 年 7 月)这个 API 依然处于测试阶段。

对于这些场景,开发者通常只能自己创造各种变通方案和临时解决办法。而当苹果最终提供那些早在 AppKit 或 UIKit 中存在了几十年的 API 时,你却不得不同时维护多套实现。

但即使你使用的 API 是 SwiftUI 第一版就已经提供的,也很有可能它后来被重新命名,或者被一个功能相近的新 API 替代。

一个典型例子就是 NavigationView。它一直以来都以 Bug 众多而闻名。看起来,苹果并没有选择修复它,而是决定直接用 NavigationStack 替换整个组件。但这又意味着,你必须同时维护两套代码分支:一套支持新系统,一套兼容旧版本。

所以,这到底算是“更少的代码”,还是“更好的代码”?你来告诉我吧,因为我自己也有点搞不清楚。

这种持续不断的 API 更替,最终导致了开发地狱。我们本应该只需要声明一次 UI 结构,但实际上,我们不得不为兼容性编写各种适配层和补丁,然后祈祷它们不会在下一次系统更新中崩溃。某种意义上,我们实际上是在替苹果完成它应该做的质量测试工作。

这些问题本应该在 2019 年解决——好吧,至少应该在 2020 年解决。然而,七年过去了,SwiftUI 依然没有实现与那些所谓“遗留”框架相同的功能完整性。SwiftUI 就像是在原地打转,而我们只能跟着它一起跑,才能勉强停留在原来的位置。

但你知道吗?如果苹果没有假装 SwiftUI 已经足够稳定,并且可以作为未来几十年的基础,这些问题其实都不会成为如此严重的问题。如果你可以直接调用最新 API 编写代码,然后将它回溯部署到旧版本 iOS 上,这些问题也不会存在。是的,你仍然需要更频繁地重构代码,逐步淘汰旧实现。但至少,当前版本的代码可以在所有设备上保持一致运行。

这也是 Android 现代 UI 框架采用的方式。Jetpack Compose 本质上只是一个通过依赖管理器获取和更新的软件包。之后,它会直接被打包进你的应用程序中,并且可以运行在最早 2014 年左右的设备上——同时还能提供完全一致的 UI 表现。

性能

接下来,我们聊聊性能。

这是一个无法掩盖的问题——即使苹果仍然试图通过只展示 SwiftUI 在最新硬件上的运行效果来淡化它。但事实是,无论苹果多少次承诺会改进,SwiftUI 的性能依然没有达到应有的标准。它并不像一个运行在“高端平台”上的“第一方核心框架”应该有的表现。

比如,这是我自己做的 UIKit 与 SwiftUI 的正面对比测试。测试内容非常简单:一个图片画廊,来自我之前版本的 Playground 应用。

为什么是之前版本?因为后来我已经使用终极跨平台框架重新构建了整个应用。不过,那是另一个故事了。

回到测试本身。即使采用了各种性能优化手段,比如在后台线程解码图片,SwiftUI 网格视图的滚动体验依然明显不够流畅。更不用说,如果你必须记住一些晦涩难懂的优化技巧,才能让它正常运行,那么 SwiftUI 最初承诺的简单性就已经荡然无存了。

这只是我进行的多个测试中的一个,而且我特意选择了一台较旧的 iPhone。但其实这不应该成为借口。因为如果你需要一颗 M5 Pro Max 级别的超级芯片,才能流畅展示一堆 JPEG 图片,那说明你的整个架构存在严重问题。

高质量软件不应该这样构建,它本来就不应该以这种方式工作。

跨平台神话

这就引出了 SwiftUI 最后的一个承诺——跨平台支持。

我看过几场早期的 SwiftUI 发布会。公平地说,我并没有在其中任何一场听到“一次编写,随处运行”(write once, run anywhere)这样的说法。苹果通常使用的表述是:“学习这些工具一次,然后将它们应用到所有平台。”

但这里存在一个问题。你在 iOS 上学到的 SwiftUI 知识,很少能够直接应用到 Mac 上的布局开发中。除非你最终想做出那种看起来格格不入的 UI——就像苹果把 iPad 应用带到 Mac 上之后的那些应用一样。

SwiftUI 的核心概念,比如数据流和组合式布局,在不同平台之间大致是一致的。但你实际使用的具体组件,以及配置这些组件的方式,往往完全不同。更不用说,同一个视图组件在不同平台上的实现方式,也可能存在差异。

换句话说,为一个 6 英寸手机设计 UI,和为一台 27 英寸桌面电脑设计 UI,本来就不是一回事。谁能想到呢?

根据我的经验,SwiftUI 所谓的“学一次,到处应用”,经常会变成:“学一次,学两遍,到处应用,处处调试。”

当然,前提是你希望构建出真正符合平台习惯、看起来专业的 UI。如果你不在意这一点,那么 SwiftUI 确实可以给你带来一些“能用”的结果,或者“差不多”的结果。

理念上的转变

事实上,我认为,这种“差不多就行”的心态才是这里最大的问题。我认为,它代表了苹果整个软件开发理念的一次重大转变。

随着 SwiftUI 的出现,我们进入了一个这样的时代:一个“大部分情况下能工作”的东西,就被认为已经足够。或者说,一个只覆盖 90% 使用场景的产品,也可以被认为是成功的。过去对于生产级质量和稳定性的要求,正在让位于所谓的“速度”。而“速度”这个词,通常是在你想要更快地发布垃圾产品时才会使用的。

在 Cocoa 时代,这是无法想象的。在 Mac OS X 的早期阶段,这种情况甚至会是一场灾难。你能想象一个 SwiftUI 版本的经典 Aqua 发布会吗?

想象一下,如果当年乔布斯没有展示那些看起来如此精美、甚至“让人想舔一下”的液态按钮,而是展示闪烁的侧边栏和不断跳动的按钮。他恐怕会被彻底嘲笑。

但现在,似乎我们正在接受“够用”的产品,以及“差不多就行”的心态。这种对于工艺品质的标准,我无法接受。

而且,这并不只是某一个框架的问题。这是一次系统性的变化。

最开始,一家公司提出“快速行动,打破常规”的理念。渐渐地,越来越多开发者加入其中。他们并不一定真的都在快速行动,但发布存在缺陷的产品,开始变得正常起来——甚至连第一方应用和系统组件也不例外。

比如,Apple Music 多年来一直存在一个 Bug:编辑播放队列时,歌曲列表会突然跳动,然后播放完全错误的歌曲。

TestFlight 会裁剪截图选择区域,而且没有任何边距。

iPad 上的设置应用会显示各种崩溃报告。

主屏幕会显示同一个应用的重复图标,状态栏会来回跳动,它还会显示一些本不应该出现的图标轮廓。

甚至像 Logic Pro 这样的专业应用,如今也会带着缺失的本地化内容发布。你知道的,就是那些本应该成为质量和稳定性标杆的专业应用。

我可以继续列举很多例子。

虽然这些问题并不全部都使用 SwiftUI,但它们反映出了苹果如今认为“可以接受”的质量标准。我并没有费很大力气去寻找这些问题;它们只是我过去几个月里亲眼遇到的事情。

所以,考虑到这些例子后,旗舰级系统框架让开发者几乎无法构建一个完全没有问题的应用,也就不足为奇了。

尤其是在苹果平台上,这种变化大约始于 2018 年,也就是我前面提到的那些“格格不入”的应用出现的时候。那时,Project Marzipan(后来更名为 Catalyst)首次允许开发者将 UIKit 代码复用于 Mac 平台。科技媒体纷纷批评这些应用的表现。

但苹果并没有选择重新打磨这些基础工作,反而进一步强化了跨平台开发的理念,并推出了 SwiftUI。而这个全新的、未经充分验证的框架,又带来了更多性能、稳定性以及视觉体验方面的问题。

我的结论是:降低质量标准是一种选择,而不是迫不得已的结果。我拒绝接受这种选择。这也是为什么,即使过去七年,SwiftUI 依然无法让我完全信任。

总结

最后,回到开头提出的问题:SwiftUI 到底出了什么问题?

如果把它存在七年时间里那些始终没有解决的问题全部考虑进去,答案就是:

一切。

或者至少,是构建稳定、高性能、可维护系统时最重要的那些部分。

SwiftUI 的故事,是一个关于平庸化和标准降低的故事。我们被要求用可预测的精确性,去交换一种虚假的便利。然后,我们被迫在两种选择之间做决定:要么花大量时间调试框架本身,要么就这样发布一个存在问题的应用。

作为一名资深工程师,我对这两个选择都没有兴趣。我无法认同“差不多能用就行”的心态,我认为用户值得拥有比“足够好”更好的产品。

SwiftUI 并不是一个真正糟糕的框架。它只是平庸。而在我看来,这反而糟糕得多。

所以,至少目前,我依然更倾向于使用那些“遗留”的 UI 框架。

后记

多年来,我一直在观察 SwiftUI 努力成为 AppKit 和 UIKit 的可靠替代品——换句话说,成为苹果早在 2019 年承诺它会成为的那个样子。

这些年来,我不断测试 SwiftUI 的每一次新版本,希望那些长期困扰它的问题最终能够得到解决。

但随着时间推移,SwiftUI 并没有在根本上变得更好。它依然像七年前一样不够成熟,而使用 SwiftUI 构建的应用,大多数也依然表现得平淡无奇。

但我观察的不只是 SwiftUI 的困境。我也一直在观察那些真心认为“只要一个 SwiftUI 功能现在能正常工作,那自己的任务就完成了”的软件工程师。

除非他们是故意选择了更差的工具,否则我其实并不完全责怪他们。

好吧,也许还是有一点。因为你无法忽视长期维护成本,而不为此付出代价。

不过,通常情况下,真正承担这个代价的并不是这些工程师个人,而是他们所在的公司。但在如今这个企业热衷于用 AI Agent 替代人类的时代,很难期待这些企业生产出的产品质量会有所提升。而这些企业,往往也是那些把软件开发视为一种商品化流程,或者线性生产过程的公司。

他们通常追求的是“快速交付”,而不是“正确交付”。我们已经开始看到这种做法带来的结果,而未来还会看到更多。

本文来自微信公众号“CSDN”,作者:Yakov Manshin;责编:苏宓,36氪经授权发布。

+1
0

好文章,需要你的鼓励

参与评论
评论千万条,友善第一条
后参与讨论
提交评论0/1000

36氪AI测评

选靠谱AI,看真实评测
查看
36氪AI测评官方交流社区
加入

36氪项目推荐

咨询项目审核和入驻
联系
36氪项目推荐订阅号
关注

下一篇

36氪APP让一部分人先看到未来
36氪
鲸准
氪空间

推送和解读前沿、有料的科技创投资讯

一级市场金融信息和系统服务提供商

聚焦全球优秀创业者,项目融资率接近97%,领跑行业