SwiftUI

27 阅读2分钟

Group(subviewsof:): 视图可以作为输入并解析它的子视图,但不是对子视图逐个进行遍历,会传回所有解析的子视图集合

ContainerValues 容器值是一种新型键控存储类似于环境和偏好等概念,沿着整个视图层次结构向下传递,偏好值沿着整个视图层次结构向上传递,到每个包含视图,特别适合实现特定于容器的定制选项

Identity: 是SwiftUI在app的多次更新中识别相同或不同元素的方式

有2种不同的身份,一种是显示标识, 一种是结构身份,区分视图

Lifetime: 生命周期是SwiftUI随时追踪视图和数据存在的方式

state lifetime = view lifetime

Dependencies: 依赖关系是SwiftUI理解你的界面何时需要更新以及为什么需要更新

标识符的稳定性至关重要,不稳定的标识符会导致更短的生命周期,拥有一个稳定的标识符,也有助于提高性能,应为SwiftUI不需要为视图创建存储,并通过新图表进行搅动。SwiftUI使用生命周期来管理持久化存储,因此稳定的标识符对于避免状态丢失也很重要

解密SwiftUI 性能

使用 lldb Self._printChanges()打印解释SwiftUI请求视图主题的原因

可以使用 let _ = Self._printChanges()不要在release环境下使用!

从资源包中查找值也很耗费资源

字符串插值通常会很耗费资源,所以你应确保缓存任何经常使用的字符串

任何堆内存分配例如类绑定类型也会增加资源消耗(初始化时,定义好类型)

SwiftUI通过身份Identity来管理视图生命周期,身份Identity的改变意味着视图的改变

List { ForEach(dogs) { dog in
    if dog.fetchToy == .ball {
        Text("")
        }
    }
}

以上代码需要构建所有视图来检索行标识符,因为它不知道每个元素会解析为多少视图

/// 这样做在原型中可能有效,但当集合扩大时,这个操作可能很快会非常耗费资源 

        List {

            ForEach(dogs.filter(...)) { dog in

                if dog.fetchToy == .ball {

                    Text("")

                }

            }

        }

因此最好是将其移出模型

List {
    ForEach(toyDogs) { dog in
        Text("")
    }
}

产生的行数等于元素数乘以每个元素产生的视图数,你要确保每个元素的视图数量是恒定的,否则SwiftUI除了标识符之外,还必须构建所有视图才能识别行 Row count = element count x views per element