内容提要
React Native 开发者质疑 SwiftUI 动画并非“原生”,因其未使用 Core Animation 的 render-server 动画。SwiftUI 共同创造者回应称这是有意取舍:动画在应用进程内推进,以换取更好的可中断性与交互性。文章还提及 Xcode 新工程格式、iOS 27 崩溃报告扩展、Vapor 5 Beta 等动态。
延伸解读
设计取舍:可中断性优先于主线程免疫
SwiftUI 将动画推进放在应用进程内,是为了获得更好的可中断性与交互性。这意味着动画能更灵活地响应状态变化,但代价是当主线程繁忙时,动画可能停滞。这种取舍并非技术退步,而是响应式框架的架构选择。
UIKit 的转向:client-side 动画成为新共识
从 iOS 18 开始,UIKit 和 AppKit 也开始采纳 client-side 动画模型,新 API 可直接使用 SwiftUI 的 Animation,并由同一套基础设施驱动。这表明苹果正在统一动画架构,逐步放弃传统的 CAAnimation 生成方式。
“原生”之争的本质:框架理念差异
React Native 开发者质疑 SwiftUI 动画不“原生”,因其未使用 Core Animation 的 render-server 动画。但 SwiftUI 共同创造者回应,这是有意为之的设计取舍。争论表面是“原生”定义,实则反映了跨平台框架与苹果原生框架在利用平台能力上的不同理念。
异步计算与主线程阻塞的局限
尽管 SwiftUI 已将部分动画和 Shape 等计算密集型工作移到后台线程,但动画推进仍属于应用进程。异步计算受状态更新和渲染流程限制,当主线程被完全阻塞时,动画依然可能停滞。这提醒开发者需关注主线程性能。
Q&A
为什么有人质疑 SwiftUI 动画不是“原生”的?
React Native 核心开发者 Krzysztof Magiera 指出,SwiftUI 没有使用 Core Animation 的 render-server animation,而是在应用进程中推进动画,因此当主线程阻塞时动画会停滞,而 UIKit 的往返动画仍能正常执行。他认为这影响了 SwiftUI 的“原生”程度。
SwiftUI 为什么选择在应用进程内推进动画?
SwiftUI 共同创造者 Kyle Macomber 解释,这是有意放弃 Server-side Animation 的设计取舍,目的是换取更好的可中断性与交互性。动画值在 client/app process 中计算和推进,而非由 Core Animation 在 render server 中推进。
SwiftUI 的 client-side animation 有什么代价?
代价是动画更容易受主线程繁忙影响,且占用更多 client 端计算资源。当主线程被完全阻塞时,动画可能停滞。不过部分动画和 Shape 等计算密集型工作已可移到后台线程,但异步计算仍受状态更新和渲染流程限制。
UIKit 和 AppKit 是否也采用了 client-side animation 模型?
是的,从 iOS 18 开始,UIKit 和 AppKit 也开始采纳这套 client-side animation 模型。新的动画 API 可以直接使用 SwiftUI 的 Animation,并由同一套动画基础设施驱动,而不再生成传统的 CAAnimation。
SwiftUI 动画在应用进程内推进,是否意味着所有插值计算都在主线程?
不是。随着 SwiftUI 演进,部分动画以及 Shape 等计算密集型工作已经可以移到后台线程,以减轻主线程压力。但由于动画推进仍属于应用进程,异步计算受状态更新和渲染流程限制,主线程完全阻塞时动画仍可能停滞。
这场争论最终反映了什么?
表面上争论 SwiftUI 是否“原生”,实际展现的是两种框架设计理念的差异。SwiftUI 选择放弃 Core Animation render-server animation 模型,以换取更灵活、更强大的动画表达能力;而 React Native 作为跨平台框架,更倾向于利用平台已有能力。