Instruments
来配置您的 SwiftUI 代码并识 identify
布局?Xcode 的仪器工具有一个梦幻般的 SwiftUI
的分析,允许我们识别次删除的频率,计算身体的速度较慢,甚至我们的国家如何随时间变化。
首先,我们需要一些能够提供有趣的结果,我们可以在乐器中看待。 因此,此代码创建一个计时器,触发每 0.01
秒,并具有显示随机 UUID
和按钮的正文视图,该按钮增加其显示它显示的值:
import Combine
import SwiftUI
class FrequentUpdater: ObservableObject {
let objectWillChange = PassthroughSubject<Void, Never>()
var timer: Timer?
init() {
timer = Timer.scheduledTimer(
withTimeInterval: 0.01,
repeats: true
) { _ in
self.objectWillChange.send()
}
}
}
struct ContentView: View {
@ObservedObject var updater = FrequentUpdater()
@State private var tapCount = 0
var body: some View {
VStack {
Text("\(UUID().uuidString)")
Button("Tap count: \(tapCount)") {
tapCount += 1
}
}
}
}
如果您在模拟器中运行该代码,则会看到它不断重绘,因为它具有始终更改的值。
注意:这是一个专门设计的压力测试,使 SwiftUI
进行大量工作,以便仪器显示我们有趣的数据 - 您不想在实际应用中使用上面的代码。
现在按 Cmd+I
通过仪器运行代码,然后选择 SwiftUI
仪器。 出现时,按 Record
按钮使其启动应用程序并开始观看。 现在让它在点击按钮10左右时运行几秒钟,然后在仪器中按停止 - 我们有足够的数据来使用。
默认情况下,SwiftUI
仪器告诉我们各种各样的事情:
这些仪器中的每一个都可以帮助您诊断和解决您的SWIFTUI应用程序中的性能问题,因此值得花时间尝试。
对于我们的小压力测试沙箱,您将看到视图身体,查看属性和核心动画提交的固体墙壁,这是一个直接的红旗。 它告诉我们,不仅是Swifui不得不经常重新创建观点,但我们的房产经常更改,因此核心动画必须加班以便跟上。
如果您选择 View Body
轨迹 - 这是仪器列表的第一行-您应该能够看到 Instruments 将结果分解为 SwiftUI 和您的项目,其中前者是原始类型,例如文本视图和按钮,后者包含您的自定义视图类型。在我们的情况下,这意味着 ContentView
应出现在自定义视图中,因为这就是我们的视图名称。
现在,您将在这里看不到的是代码到 SwiftUI
视图的完美一对一映射,因为 SwiftUI
会主动折叠其视图层次结构以减少工作量。因此,不要期望在代码中看到任何 VStack
创建内容-该应用程序实际上是免费的。
在此屏幕上,重要的数字是“计数”和“平均持续时间” –每件事创建了多少次,花费了多长时间。由于这是一个压力测试,您应该会看到Count的数字很高,但是我们的布局微不足道,因此Avg Duration可能只有几十微秒。
接下来,选择View Properties
轨道,它是仪器列表中的第二行。这将显示所有视图的所有属性,包括它们的当前值和所有先前的值。
我们的示例应用程序具有一个按钮,可在点击时通过将一个数字添加一个按钮来更改其标签,并且该按钮在此工具中就可见了-查找视图类型 ContentView
和属性类型 State<Int>
。
遗憾的是,Instruments无法(尚未?)向我们显示确切的属性名称,如果您要跟踪几条整数状态,则可能会更加令人困惑。但是,它确实有一个不同的技巧:在记录窗口的顶部是一个标记当前视图位置的箭头,如果在周围拖动它,您将确切地看到应用程序状态随时间的变化–每次您轻按按钮,您将看到状态整数加1,并且您可以向前和向后滚动以查看它的发生。
这可以释放巨大的力量,因为它可以让我们直接查看状态更改何时导致缓慢的重绘或其他工作-就像是在时光机中,您可以在其运行期间随时检查应用程序的确切状态。
尽管 SwiftUI
可以直接使用 Metal
来提高性能,但大多数情况下,它更喜欢使用 Core Animation
进行渲染。 这意味着我们会自动从 Instruments
获得内置的 Core Animation
分析工具,包括检测昂贵提交的功能。
当将多个更改放到一个组中(称为事务)时,Core Animation
效果最佳。 我们有效地在一个事务中堆叠了一部分工作,然后要求 CA
继续进行工作-称为提交事务。
因此,当 Instruments
向我们展示昂贵的 Core Animation
提交时,真正向我们展示的是 SwiftUI
由于更新而被迫在屏幕上重新绘制像素的次数。 从理论上讲,这仅应在应用程序的实际状态导致不同的视图层次结构时发生,因为 SwiftUI
应该能够将 body
属性的新输出与先前的输出进行比较。
最后一个重要的轨道是最后一个轨道,即 Time Profiler
,它向我们显示了在代码的每个部分中花费了多少时间。 该工具的工作方式与 Instruments
中的常规时间分析器相同,但是如果您以前没有尝试过,则至少需要了解以下内容:
尽管时间分析器对于识别性能问题非常有用,但是通常只要查看最重的堆栈跟踪就会突出显示最大的问题。
在冲销概要分析自己的代码之前,需要注意以下几点:
Instruments
中看到了纯色条,它们也只能从远处观看-您可以通过按住 Cmd
并按 -
和 +
进行缩放以查看更多详细信息