If you create a very simple example that shows a lot of leaking object within the SwiftUI code if you nest NavigationView/List/ForEach
and return different types of views in the ForEach
closure.
import SwiftUI
class MyStateObject : ObservableObject {
@Published var items:[Int]
init() {
self.items = Array(0..<1000)
}
}
struct ContentView: View {
@StateObject var stateObject = MyStateObject()
var body: some View {
NavigationView {
List {
ForEach(stateObject.items, id: \.self) { item in
if(item % 2 == 0) {
Text("Even \(item)")
}
else {
Image(systemName: "xmark.octagon")
}
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
I strongly suspect this is a bug in SwiftUI but I wanted to ask if I am doing anything wrong here.
You can see the leaks by attaching Instruments. It will show immediately and increase if you scroll through the list.
Interestingly, it seems the leaks don't happen if
- you remove the
NavigationView
from the hierarchy. - you only supply one type of
View
inForEach
(and don't branch via if/else). - the list of items you want to show is small (100 does not seem to result in leaks).
(Tested on XCode 12.5 and iOS 14.5 Simulator and Device,)
Since in my app I am pretty much reliant on this kind of hierarchy, I am very open for some suggestions on how to avoid the leaking.