实时快路径
高频状态更新、二进制属性通道和实时 UI 的边界。
实时快路径是 appui 的高频界面更新通道。它的目标不是让你手动操作更新机制,而是在状态变化很频繁时,让已经显示出来的原生控件尽量只更新必要属性。
你可以把它理解为:首屏仍然由 appui 正常构建,运行时如果只是文本、滑块、开关、进度、图片等属性变化,系统会优先走更轻的更新路径。
#预期效果
示例会展示普通 State 与 ReactiveState 在高频属性更新时的可见差异。
#什么时候有用
- 滑块、计时器、仪表盘、进度条持续变化。
- 文本、标签、数值、状态灯需要频繁刷新。
- 页面结构基本不变,只是已有控件的值在变。
- 你希望减少整棵界面反复重建带来的卡顿。
#什么时候不需要关注
- 页面只是普通表单、设置页或低频按钮操作。
- 你正在增删列表行、切换导航根、打开 sheet 或重排布局。
- 你的界面每次变化都需要重新组织视图结构。
这些场景继续使用普通 State 和 appui 组件即可。实时快路径会在适合的地方自动参与,不需要你把简单界面写复杂。
#推荐写法
优先从清晰的状态模型开始:
已复制
import appui
state = appui.State(progress=0.4, title="下载中")
def body():
return appui.VStack([
appui.Text(state.title),
appui.ProgressView(value=state.progress),
appui.Button("增加进度", action=bump),
], spacing=16).padding()
def bump():
state.progress = min(1.0, state.progress + 0.1)
if state.progress >= 1.0:
state.title = "已完成"
appui.run(body, state=state, presentation="sheet")
如果一个值会高频变化,再考虑 ReactiveState。它适合把频繁变化的字段和界面控件绑定起来,让系统选择更轻的刷新方式。
已复制
import appui
state = appui.ReactiveState(value=0.5)
def value_label():
return f"{state.value:.0%}"
def body():
return appui.VStack([
appui.Text("音量"),
appui.Slider(**appui.bind(state, "value"), label="音量"),
appui.Text(value_label()),
], spacing=16).padding()
appui.run(body, state=state, presentation="sheet")
#使用原则
- 先写正确的
appui界面,再优化高频字段。 - 高频值用
ReactiveState或组件已有绑定,不要自己维护一套刷新系统。 - 结构变化交给普通
State重建,属性变化交给系统尽量增量刷新。 - 不要依赖未公开常量或未文档化接口。
#和性能优化的关系
实时快路径只解决“已有控件高频改值”的成本。真正流畅的界面还需要:
- 列表使用
List/ForEach,不要用大量VStack模拟。 - 大文件、网络、图片处理放到后台任务。
- 避免在
body()中做复杂计算、排序或同步文件读取。 - 控件数量很大时,优先拆分页面或懒加载。
更多整体建议见 性能实践。
#系统实时能力
如果实时数据来自相机、传感器、麦克风、键盘高度、深浅色变化或照片选择,请看 iOS 原生能力。这些能力需要明确的启动和停止路径,不适合在普通 body() 重建循环中轮询。