У меня есть вопрос о том, как работает управление памятью в стеке SwiftUI NavigationView. У меня есть представление, в котором я объявил NavigationView и NavigationLink, внутри параметра назначения NavigationLink мой TestView. Навигация работает хорошо, но когда я выскакиваю из стека (например, кнопка «назад»), deinit не печатается в консоли, и TestViewModel все еще можно найти в графе памяти. Как деинициализировать мой TestViewModel, когда он больше не нужен?
/// First view in application
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
Text("Hello, leak!")
NavigationLink(
destination: TestView(viewModel: TestViewModel()),
label: { Text("Create leak ?♂️") }
)
}
}
}
}
/// Just simple class for init and deinit print
class TestViewModel: ObservableObject {
@Published var text = "Test"
init() {
print("TestViewModel init")
}
deinit {
print("TestViewModel deinit")
}
}
/// Second view, which is poped from stack
private struct TestView: View {
@ObservedObject var viewModel: TestViewModel
var body: some View {
Text(viewModel.text)
}
}
ОБНОВЛЕНИЕ Добавлен снимок экрана с графиком памяти, который я заранее забыл.
![Memory graph screenshot bottom part](https://i.stack.imgur.com/kAxo4.png)
![Memory graph screenshot top part](https://i.stack.imgur.com/b7HXi.png)
ОБНОВЛЕНИЕ
Проверено на реальном устройстве, где работает навигация. Похоже, что модель представления не деинициализируется при всплывающем представлении, а инициализируется снова при нажатии в другой раз. Но вопрос все еще остается, есть ли способ деинформировать модель представления при выводе представления в стек навигации?
TestViewModel init
TestViewModel deinit
TestViewModel init
Кроме того, когда я добавляю другое представление в стек, поведение немного меняется. Теперь вторая модель представления вида вызовет утечку, но первая будет деинициализирована, как и ожидалось.
First view push
TestViewModel init
Second view push
TestViewModel2 init
Second view pop
First view pop
TestViewModel deinit