SwiftUI - Hiding LazyVGrid causes memory leak

吃可爱长大的小学妹 提交于 2020-12-07 04:36:47

问题


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 on apples side? Maybe theres a workaround?

import SwiftUI
import Foundation
import Combine

enum FakeAPI {
    static var fakeData: [Result] {
       return [
            Result(id: 1), Result(id: 2), Result(id: 3), Result(id: 4), Result(id: 5),
            Result(id: 6), Result(id: 7), Result(id: 8), Result(id: 9), Result(id: 10),
            Result(id: 11), Result(id: 12), Result(id: 13), Result(id: 14), Result(id: 15),
            Result(id: 16), Result(id: 17), Result(id: 18), Result(id: 19), Result(id: 20),
            Result(id: 21), Result(id: 22), Result(id: 23), Result(id: 24), Result(id: 25),
            Result(id: 26), Result(id: 27), Result(id: 28), Result(id: 29), Result(id: 30)
       ]
    }

    static func fetchData() -> AnyPublisher<[Result], Error> {
        return Just(fakeData)
            .mapError({ $0 as Error })
            .eraseToAnyPublisher()
    }
}

struct Result: Identifiable {
    let id: Int
}

struct ContentView: View {
    @StateObject private var vm: ViewModel = ViewModel()

    let columns = [
        GridItem(.adaptive(minimum: 200), alignment: .top),
        GridItem(.adaptive(minimum: 200), alignment: .top)
    ]

    var body: some View {
        NavigationView {
            ScrollView {
                Button {
                    vm.hide = true
                } label: {
                    Text("Hide")
                }
                if !vm.hide {
                    LazyVGrid(columns: columns) {
                        ForEach(vm.results) { result in
                            Text("\(result.id)")
                                .frame(width: 120, height: 120)
                                .background(Color.red)
                        }
                    }
                }
            }
            .navigationTitle("Grid Memory Leak")
            .onAppear {
                vm.load()
            }
        }
    }
}

final class ViewModel: ObservableObject {
    @Published private(set) var results: [Result] = []
    @Published var hide = false

    private var subscriptions = Set<AnyCancellable>()

    func load() -> Void {
        FakeAPI.fetchData()
            .sink(receiveCompletion: { _ in }, receiveValue: { [weak self] results in
                self?.results = results
            })
            .store(in: &subscriptions)
    }
}

来源:https://stackoverflow.com/questions/64627309/swiftui-hiding-lazyvgrid-causes-memory-leak

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!