Post

Replies

Boosts

Views

Activity

Hiding LazyVGrid causes memory leak
I have a LazyVGrid that displays some data fetched from a remote API. When hiding the LazyVGrid via a button press, I encounter a memory leak. This seems to happen only if there is more content than can be displayed inside of LazyVGrid. I have prepared some code for you to reproduce this leak. Is there something flaut with this code, or ist that a bug with the LazyVGrid? Maybe theres a workaround? import SwiftUI import Foundation import Combine enum FakeAPI { &#9;&#9;static var fakeData: [Result] { &#9;&#9;&#9; return [ &#9;&#9;&#9;&#9;&#9;&#9;Result(id: 1), Result(id: 2), Result(id: 3), Result(id: 4), Result(id: 5), &#9;&#9;&#9;&#9;&#9;&#9;Result(id: 6), Result(id: 7), Result(id: 8), Result(id: 9), Result(id: 10), &#9;&#9;&#9;&#9;&#9;&#9;Result(id: 11), Result(id: 12), Result(id: 13), Result(id: 14), Result(id: 15), &#9;&#9;&#9;&#9;&#9;&#9;Result(id: 16), Result(id: 17), Result(id: 18), Result(id: 19), Result(id: 20), &#9;&#9;&#9;&#9;&#9;&#9;Result(id: 21), Result(id: 22), Result(id: 23), Result(id: 24), Result(id: 25), &#9;&#9;&#9;&#9;&#9;&#9;Result(id: 26), Result(id: 27), Result(id: 28), Result(id: 29), Result(id: 30) &#9;&#9;&#9; ] &#9;&#9;} &#9;&#9;static func fetchData() -> AnyPublisher<[Result], Error> { &#9;&#9;&#9;&#9;return Just(fakeData) &#9;&#9;&#9;&#9;&#9;&#9;.mapError({ $0 as Error }) &#9;&#9;&#9;&#9;&#9;&#9;.eraseToAnyPublisher() &#9;&#9;} } struct Result: Identifiable { &#9;&#9;let id: Int } struct ContentView: View { &#9;&#9;@StateObject private var vm: ViewModel = ViewModel() &#9;&#9;let columns = [ &#9;&#9;&#9;&#9;GridItem(.adaptive(minimum: 200), alignment: .top), &#9;&#9;&#9;&#9;GridItem(.adaptive(minimum: 200), alignment: .top) &#9;&#9;] &#9;&#9;var body: some View { &#9;&#9;&#9;&#9;NavigationView { &#9;&#9;&#9;&#9;&#9;&#9;ScrollView { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Button { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;vm.hide = true &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} label: { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Text("Hide") &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;if !vm.hide { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;LazyVGrid(columns: columns) { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;ForEach(vm.results) { result in &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Text("\(result.id)") &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;.frame(width: 120, height: 120) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;.background(Color.red) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;.navigationTitle("Grid Memory Leak") &#9;&#9;&#9;&#9;&#9;&#9;.onAppear { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;vm.load() &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;} &#9;&#9;} } final class ViewModel: ObservableObject { &#9;&#9;@Published private(set) var results: [Result] = [] &#9;&#9;@Published var hide = false &#9;&#9;private var subscriptions = Set<AnyCancellable>() &#9;&#9;func load() -> Void { &#9;&#9;&#9;&#9;FakeAPI.fetchData() &#9;&#9;&#9;&#9;&#9;&#9;.sink(receiveCompletion: { _ in }, receiveValue: { [weak self] results in &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;self?.results = results &#9;&#9;&#9;&#9;&#9;&#9;}) &#9;&#9;&#9;&#9;&#9;&#9;.store(in: &subscriptions) &#9;&#9;} }
0
0
559
Nov ’20