【问题标题】:Why are objects still in memory after emptying NavigationStack path?为什么清空 NavigationStack 路径后对象仍在内存中?
【发布时间】:2022-10-05 06:00:48
【问题描述】:

我正在尝试实现一个协调器来管理流程。状态存储在 CoordinatorStore 中。有 2 个 @Published 属性用于管理流。这屏幕属性控制当前显示的视图和小路控制堆栈视图的导航堆栈。可以在下面找到实现的详细信息。

使用当前实施并在以下操作之后:秀A->展会->显示首字母

我希望 StoreS 和 Store 将从内存中释放,因为小路,它通过枚举关联值保存 StoreA 和 StoreB,被清空。

但这不会发生,如果我再次重复这些操作,内存中就会有 2 个 StoreA 和 2 个 StoreB 等等。我错过了什么吗?

在执行初始操作集后,我还将附上内存调试器快照的屏幕截图。

enum Path: Hashable {
    case a(StoreA)
    case b(StoreB)
}

enum Screen {
    case initial
    case stack
}

final class CoordinatorStore: ObservableObject {
    @Published var path: [Path] = []
    @Published var screen: Screen = .stack
    
    func showA() {
        let store = StoreA()
        path.append(.a(store))
    }
    
    func showB() {
        let store = StoreB()
        path.append(.b(store))
    }
    
    func showInitial() {
        path = []
        screen = .initial
    }
    
    func showStack() {
        screen = .stack
    }
}
struct Coordinator: View {
    @ObservedObject var store: CoordinatorStore
    
    var body: some View {
        switch store.screen {
        case .initial: initial
        case .stack: stack
        }
    }
    
    var stack: some View {
        NavigationStack(path: $store.path) {
            VStack {
                Text("Root")
            }
            .toolbar {
                Button(action: self.store.showA) {
                    Text("Push A")
                }
            }
            .navigationDestination(for: Path.self) { path in
                switch path {
                case .a(let store):
                    ViewA(store: store)
                        .toolbar {
                            Button(action: self.store.showB) {
                                Text("Push B")
                            }
                        }
                case .b(let store):
                    ViewB(store: store)
                        .toolbar {
                            Button(action: self.store.showInitial) {
                                Text("Show Initial")
                            }
                        }
                }
            }
        }
    }
    
    var initial: some View {
        VStack {
            Text("Initial")
            Button(action: store.showStack) {
                Text("Go to Stack")
            }
        }
    }
}
struct ViewA: View {
    @ObservedObject var store: StoreA
    
    var body: some View {
        Text("View A")
    }
}

final class StoreA: NSObject, ObservableObject {
    deinit {
        print("Deinit: \(String(describing: self))")
    }
}
struct ViewB: View {
    @ObservedObject var store: StoreB
    
    var body: some View {
        Text("View B")
    }
}

final class StoreB: NSObject, ObservableObject {
    deinit {
        print("Deinit: \(String(describing: self))")
    }
}

【问题讨论】:

    标签: ios swift swiftui memory-leaks swiftui-navigationstack


    【解决方案1】:

    我相信这与以下内容相关但不完全相同:

    Navigation api 似乎优先考虑某些东西必须始终出现在屏幕上的效率(init 很昂贵)。在替换初始化并出现之前,它似乎不会取消初始化已经消失的视图。

    如果您尝试使用 Navigation 框架之外的东西来管理 Navigation 框架视图,这可能会导致内存泄漏 (I believe),但只要 Navigation 框架继续负责,事情就会被删除最终,但直到新视图被初始化。

    【讨论】:

      猜你喜欢
      • 2019-12-21
      • 2013-05-11
      • 1970-01-01
      • 1970-01-01
      • 2011-06-16
      • 1970-01-01
      • 2020-03-21
      • 2011-10-02
      • 2022-01-10
      相关资源
      最近更新 更多