Skip to content

Commit a1efffd

Browse files
committed
Split ContentRootView into 2 views, cache dyldSharedCacheImageRootNode
for performance improvements. ContentRootView no longer needs to redraw very often and when it does, dyldSharedCacheImageRootNode does not need to re-compute the tree
1 parent 7f01d6a commit a1efffd

File tree

1 file changed

+45
-35
lines changed

1 file changed

+45
-35
lines changed

HeaderViewer/ContentView.swift

Lines changed: 45 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,34 @@ struct ContentView: View {
3131
}
3232
}
3333

34+
struct ContentRootView: View {
35+
private static let dscRootNode = CDUtilities.dyldSharedCacheImageRootNode
36+
37+
@Binding var selectedObject: RuntimeObjectType?
38+
39+
var body: some View {
40+
NavigationStack {
41+
AllRuntimeObjectsView(selectedObject: $selectedObject)
42+
.navigationTitle("Header Viewer")
43+
.toolbar {
44+
ToolbarItem {
45+
NavigationLink(value: Self.dscRootNode) {
46+
Label("System Images", systemImage: "folder")
47+
}
48+
}
49+
}
50+
.navigationDestination(for: NamedNode.self) { namedNode in
51+
if namedNode.isLeaf {
52+
ImageClassPicker(namedNode: namedNode, selection: $selectedObject)
53+
} else {
54+
NamedNodeView(node: namedNode)
55+
.environmentObject(RuntimeListings.shared)
56+
}
57+
}
58+
}
59+
}
60+
}
61+
3462
private enum RuntimeTypeSearchScope: Hashable {
3563
case all
3664
case classes
@@ -54,7 +82,7 @@ private extension RuntimeTypeSearchScope {
5482
}
5583
}
5684

57-
private class ContentRootViewModel: ObservableObject {
85+
private class AllRuntimeObjectsViewModel: ObservableObject {
5886
let runtimeListings: RuntimeListings = .shared
5987

6088
@Published var searchString: String
@@ -99,47 +127,29 @@ private class ContentRootViewModel: ObservableObject {
99127
}
100128
}
101129

102-
struct ContentRootView: View {
103-
@StateObject private var viewModel: ContentRootViewModel
130+
private struct AllRuntimeObjectsView: View {
131+
@StateObject private var viewModel: AllRuntimeObjectsViewModel
104132
@Binding var selectedObject: RuntimeObjectType?
105133

106134
init(selectedObject: Binding<RuntimeObjectType?>) {
107-
_viewModel = StateObject(wrappedValue: ContentRootViewModel())
135+
_viewModel = StateObject(wrappedValue: AllRuntimeObjectsViewModel())
108136
_selectedObject = selectedObject
109137
}
110138

111139
var body: some View {
112-
NavigationStack {
113-
let runtimeObjects = viewModel.runtimeObjects
114-
ListView(runtimeObjects, selection: $selectedObject) { runtimeObject in
115-
RuntimeObjectRow(type: runtimeObject)
116-
}
117-
.id(runtimeObjects) // don't try to diff the List
118-
.searchable(text: $viewModel.searchString)
119-
.searchScopes($viewModel.searchScope) {
120-
Text("All")
121-
.tag(RuntimeTypeSearchScope.all)
122-
Text("Classes")
123-
.tag(RuntimeTypeSearchScope.classes)
124-
Text("Protocols")
125-
.tag(RuntimeTypeSearchScope.protocols)
126-
}
127-
.navigationTitle("Header Viewer")
128-
.toolbar {
129-
ToolbarItem {
130-
NavigationLink(value: CDUtilities.dyldSharedCacheImageRootNode) {
131-
Label("System Images", systemImage: "folder")
132-
}
133-
}
134-
}
135-
.navigationDestination(for: NamedNode.self) { namedNode in
136-
if namedNode.isLeaf {
137-
ImageClassPicker(namedNode: namedNode, selection: $selectedObject)
138-
} else {
139-
NamedNodeView(node: namedNode)
140-
.environmentObject(RuntimeListings.shared)
141-
}
142-
}
140+
let runtimeObjects = viewModel.runtimeObjects
141+
ListView(runtimeObjects, selection: $selectedObject) { runtimeObject in
142+
RuntimeObjectRow(type: runtimeObject)
143+
}
144+
.id(runtimeObjects) // don't try to diff the List
145+
.searchable(text: $viewModel.searchString)
146+
.searchScopes($viewModel.searchScope) {
147+
Text("All")
148+
.tag(RuntimeTypeSearchScope.all)
149+
Text("Classes")
150+
.tag(RuntimeTypeSearchScope.classes)
151+
Text("Protocols")
152+
.tag(RuntimeTypeSearchScope.protocols)
143153
}
144154
}
145155
}

0 commit comments

Comments
 (0)